/kernel/branches/Kolibri-acpi/blkdev/rd.inc |
---|
0,0 → 1,2272 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; RAMDISK functions ;; |
;; (C) 2004 Ville Turjanmaa, License: GPL ;; |
;; Addings by M.Lisovin ;; |
;; LFN support by diamond ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; calculate fat chain |
calculatefatchain: |
pushad |
mov esi,RAMDISK+512 |
mov edi,RAMDISK_FAT |
fcnew: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
mov ecx,dword [esi+8] |
mov edx,ecx |
shr edx,4 ;8 ok |
shr dx,4 ;7 ok |
xor ch,ch |
shld ecx,ebx,20 ;6 ok |
shr cx,4 ;5 ok |
shld ebx,eax,12 |
and ebx,0x0fffffff ;4 ok |
shr bx,4 ;3 ok |
shl eax,4 |
and eax,0x0fffffff ;2 ok |
shr ax,4 ;1 ok |
mov dword [edi],eax |
mov dword [edi+4],ebx |
mov dword [edi+8],ecx |
mov dword [edi+12],edx |
add edi,16 |
add esi,12 |
cmp edi,RAMDISK_FAT+2856*2 ;2849 clusters |
jnz fcnew |
popad |
ret |
restorefatchain: ; restore fat chain |
pushad |
mov esi,RAMDISK_FAT |
mov edi,RAMDISK+512 |
fcnew2: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
shl ax,4 |
shl eax,4 |
shl bx,4 |
shr ebx,4 |
shrd eax,ebx,8 |
shr ebx,8 |
mov dword [edi],eax |
mov word [edi+4],bx |
add edi,6 |
add esi,8 |
cmp edi,RAMDISK+512+4278 ;4274 bytes - all used FAT |
jb fcnew2 |
mov esi,RAMDISK+512 ; duplicate fat chain |
mov edi,RAMDISK+512+0x1200 |
mov ecx,1069 ;4274/4 |
cld |
rep movsd |
popad |
ret |
ramdisk_free_space: |
;--------------------------------------------- |
; |
; returns free space in edi |
; rewr.by Mihasik |
;--------------------------------------------- |
push eax ebx ecx |
mov edi,RAMDISK_FAT ;start of FAT |
xor ax,ax ;Free cluster=0x0000 in FAT |
xor ebx,ebx ;counter |
mov ecx,2849 ;2849 clusters |
cld |
rdfs1: |
repne scasw |
jnz rdfs2 ;if last cluster not 0 |
inc ebx |
test ecx, ecx |
jnz rdfs1 |
rdfs2: |
shl ebx,9 ;free clusters*512 |
mov edi,ebx |
pop ecx ebx eax |
ret |
expand_filename: |
;--------------------------------------------- |
; |
; exapand filename with '.' to 11 character |
; eax - pointer to filename |
;--------------------------------------------- |
push esi edi ebx |
mov edi,esp ; check for '.' in the name |
add edi,12+8 |
mov esi,eax |
mov eax,edi |
mov [eax+0],dword ' ' |
mov [eax+4],dword ' ' |
mov [eax+8],dword ' ' |
flr1: |
cmp [esi],byte '.' |
jne flr2 |
mov edi,eax |
add edi,7 |
jmp flr3 |
flr2: |
mov bl,[esi] |
mov [edi],bl |
flr3: |
inc esi |
inc edi |
mov ebx,eax |
add ebx,11 |
cmp edi,ebx |
jbe flr1 |
pop ebx edi esi |
ret |
fileread: |
;---------------------------------------------------------------- |
; |
; fileread - sys floppy |
; |
; eax points to filename 11 chars |
; ebx first wanted block ; 1+ ; if 0 then set to 1 |
; ecx number of blocks to read ; 1+ ; if 0 then set to 1 |
; edx mem location to return data |
; esi length of filename 12*X 0=root |
; |
; ret ebx = size or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
test ebx,ebx ;if ebx=0 - set to 1 |
jnz frfl5 |
inc ebx |
frfl5: |
test ecx,ecx ;if ecx=0 - set to 1 |
jnz frfl6 |
inc ecx |
frfl6: |
test esi,esi ; return ramdisk root |
jnz fr_noroot ;if not root |
cmp ebx,14 ;14 clusters=root dir |
ja oorr |
cmp ecx,14 |
ja oorr |
jmp fr_do |
oorr: |
mov eax,5 ;out of root range (fnf) |
xor ebx,ebx |
dec ebx ;0xffffffff |
ret |
fr_do: ;reading rootdir |
mov edi,edx |
dec ebx |
push edx |
mov edx,ecx |
add edx,ebx |
cmp edx,15 ;ebx+ecx=14+1 |
pushf |
jbe fr_do1 |
sub edx,14 |
sub ecx,edx |
fr_do1: |
shl ebx,9 |
mov esi,RAMDISK+512*19 |
add esi,ebx |
shl ecx,7 |
cld |
rep movsd |
popf |
pop edx |
jae fr_do2 |
xor eax,eax ; ok read |
xor ebx,ebx |
ret |
fr_do2: ;if last cluster |
mov eax,6 ;end of file |
xor ebx,ebx |
ret |
fr_noroot: |
sub esp,32 |
call expand_filename |
dec ebx |
push eax |
push eax ebx ecx edx esi edi |
call rd_findfile |
je fifound |
add esp,32+28 ;if file not found |
ret |
fifound: |
mov ebx,[edi-11+28] ;file size |
mov [esp+20],ebx |
mov [esp+24],ebx |
add edi,0xf |
movzx eax,word [edi] |
mov edi,eax ;edi=cluster |
frnew: |
add eax,31 ;bootsector+2*fat+filenames |
shl eax,9 ;*512 |
add eax,RAMDISK ;image base |
mov ebx,[esp+8] |
mov ecx,512 ;[esp+4] |
cmp [esp+16],dword 0 ; wanted cluster ? |
jne frfl7 |
call memmove |
add [esp+8],dword 512 |
dec dword [esp+12] ; last wanted cluster ? |
je frnoread |
jmp frfl8 |
frfl7: |
dec dword [esp+16] |
frfl8: |
movzx eax,word [edi*2+RAMDISK_FAT] ; find next cluster from FAT |
mov edi,eax |
cmp edi,4095 ;eof - cluster |
jz frnoread2 |
cmp [esp+24],dword 512 ;eof - size |
jb frnoread |
sub [esp+24],dword 512 |
jmp frnew |
frnoread2: |
cmp [esp+16],dword 0 ; eof without read ? |
je frnoread |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
mov eax,6 ; end of file |
ret |
frnoread: |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
xor eax,eax ;read ok |
ret |
rd_findfile: |
;by Mihasik |
;IN: eax - pointer to filename OUT: filestring+11 in edi or notZero in flags and fnf in eax,ebx |
mov edi,RAMDISK+512*18+512 ;Point at directory |
cld |
rd_newsearch: |
mov esi,eax |
mov ecx,11 |
rep cmpsb |
je rd_ff |
add cl,21 |
add edi,ecx |
cmp edi,RAMDISK+512*33 |
jb rd_newsearch |
mov eax,5 ;if file not found - eax=5 |
xor ebx,ebx |
dec ebx ;ebx=0xffffffff and zf=0 |
rd_ff: |
ret |
; \begin{diamond} |
uni2ansi_str: |
; convert UNICODE zero-terminated string to ASCII-string (codepage 866) |
; in: esi->source, edi->buffer (may be esi=edi) |
; destroys: eax,esi,edi |
lodsw |
test ax, ax |
jz .done |
cmp ax, 0x80 |
jb .ascii |
cmp ax, 0x401 |
jz .yo1 |
cmp ax, 0x451 |
jz .yo2 |
cmp ax, 0x410 |
jb .unk |
cmp ax, 0x440 |
jb .rus1 |
cmp ax, 0x450 |
jb .rus2 |
.unk: |
mov al, '_' |
jmp .doit |
.yo1: |
mov al, 'ð' |
jmp .doit |
.yo2: |
mov al, 'ñ' |
jmp .doit |
.rus1: |
; 0x410-0x43F -> 0x80-0xAF |
add al, 0x70 |
jmp .doit |
.rus2: |
; 0x440-0x44F -> 0xE0-0xEF |
add al, 0xA0 |
.ascii: |
.doit: |
stosb |
jmp uni2ansi_str |
.done: |
mov byte [edi], 0 |
ret |
ansi2uni_char: |
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding |
mov ah, 0 |
; 0x00-0x7F - trivial map |
cmp al, 0x80 |
jb .ret |
; 0x80-0xAF -> 0x410-0x43F |
cmp al, 0xB0 |
jae @f |
add ax, 0x410-0x80 |
.ret: |
ret |
@@: |
; 0xE0-0xEF -> 0x440-0x44F |
cmp al, 0xE0 |
jb .unk |
cmp al, 0xF0 |
jae @f |
add ax, 0x440-0xE0 |
ret |
; 0xF0 -> 0x401 |
; 0xF1 -> 0x451 |
@@: |
cmp al, 'ð' |
jz .yo1 |
cmp al, 'ñ' |
jz .yo2 |
.unk: |
mov al, '_' ; ah=0 |
ret |
.yo1: |
mov ax, 0x401 |
ret |
.yo2: |
mov ax, 0x451 |
ret |
char_toupper: |
; convert character to uppercase, using cp866 encoding |
; in: al=symbol |
; out: al=converted symbol |
cmp al, 'a' |
jb .ret |
cmp al, 'z' |
jbe .az |
cmp al, 'ñ' |
jz .yo1 |
cmp al, ' ' |
jb .ret |
cmp al, 'à' |
jb .rus1 |
cmp al, 'ï' |
ja .ret |
; 0xE0-0xEF -> 0x90-0x9F |
sub al, 'à'-'' |
.ret: |
ret |
.rus1: |
; 0xA0-0xAF -> 0x80-0x8F |
.az: |
and al, not 0x20 |
ret |
.yo1: |
; 0xF1 -> 0xF0 |
dec ax |
ret |
fat_get_name: |
; in: edi->FAT entry |
; out: CF=1 - no valid entry |
; else CF=0 and ebp->ASCIIZ-name |
; (maximum length of filename is 255 (wide) symbols without trailing 0, |
; but implementation requires buffer 261 words) |
; destroys eax |
cmp byte [edi], 0 |
jz .no |
cmp byte [edi], 0xE5 |
jnz @f |
.no: |
stc |
ret |
@@: |
cmp byte [edi+11], 0xF |
jz .longname |
test byte [edi+11], 8 |
jnz .no |
push ecx |
push edi ebp |
test byte [ebp-4], 1 |
jnz .unicode_short |
mov eax, [edi] |
mov ecx, [edi+4] |
mov [ebp], eax |
mov [ebp+4], ecx |
mov ecx, 8 |
@@: |
cmp byte [ebp+ecx-1], ' ' |
loope @b |
mov eax, [edi+8] |
cmp al, ' ' |
je .done |
shl eax, 8 |
mov al, '.' |
lea ebp, [ebp+ecx+1] |
mov [ebp], eax |
mov ecx, 3 |
@@: |
rol eax, 8 |
cmp al, ' ' |
jne .done |
loop @b |
dec ebp |
.done: |
and byte [ebp+ecx+1], 0 ; CF=0 |
pop ebp edi ecx |
ret |
.unicode_short: |
mov ecx, 8 |
push ecx |
@@: |
mov al, [edi] |
inc edi |
call ansi2uni_char |
mov [ebp], ax |
inc ebp |
inc ebp |
loop @b |
pop ecx |
@@: |
cmp word [ebp-2], ' ' |
jnz @f |
dec ebp |
dec ebp |
loop @b |
@@: |
mov word [ebp], '.' |
inc ebp |
inc ebp |
mov ecx, 3 |
push ecx |
@@: |
mov al, [edi] |
inc edi |
call ansi2uni_char |
mov [ebp], ax |
inc ebp |
inc ebp |
loop @b |
pop ecx |
@@: |
cmp word [ebp-2], ' ' |
jnz @f |
dec ebp |
dec ebp |
loop @b |
dec ebp |
dec ebp |
@@: |
and word [ebp], 0 ; CF=0 |
pop ebp edi ecx |
ret |
.longname: |
; LFN |
mov al, byte [edi] |
and eax, 0x3F |
dec eax |
cmp al, 20 |
jae .no ; ignore invalid entries |
mov word [ebp+260*2], 0 ; force null-terminating for orphans |
imul eax, 13*2 |
add ebp, eax |
test byte [edi], 0x40 |
jz @f |
mov word [ebp+13*2], 0 |
@@: |
push eax |
; now copy name from edi to ebp ... |
mov eax, [edi+1] |
mov [ebp], eax ; symbols 1,2 |
mov eax, [edi+5] |
mov [ebp+4], eax ; 3,4 |
mov eax, [edi+9] |
mov [ebp+8], ax ; 5 |
mov eax, [edi+14] |
mov [ebp+10], eax ; 6,7 |
mov eax, [edi+18] |
mov [ebp+14], eax ; 8,9 |
mov eax, [edi+22] |
mov [ebp+18], eax ; 10,11 |
mov eax, [edi+28] |
mov [ebp+22], eax ; 12,13 |
; ... done |
pop eax |
sub ebp, eax |
test eax, eax |
jz @f |
; if this is not first entry, more processing required |
stc |
ret |
@@: |
; if this is first entry: |
test byte [ebp-4], 1 |
jnz .ret |
; buffer at ebp contains UNICODE name, convert it to ANSI |
push esi edi |
mov esi, ebp |
mov edi, ebp |
call uni2ansi_str |
pop edi esi |
.ret: |
clc |
ret |
fat_compare_name: |
; compares ASCIIZ-names, case-insensitive (cp866 encoding) |
; in: esi->name, ebp->name |
; out: if names match: ZF=1 and esi->next component of name |
; else: ZF=0, esi is not changed |
; destroys eax |
push ebp esi |
.loop: |
mov al, [ebp] |
inc ebp |
call char_toupper |
push eax |
lodsb |
call char_toupper |
cmp al, [esp] |
jnz .done |
pop eax |
test al, al |
jnz .loop |
dec esi |
pop eax |
pop ebp |
xor eax, eax ; set ZF flag |
ret |
.done: |
cmp al, '/' |
jnz @f |
cmp byte [esp], 0 |
jnz @f |
mov [esp+4], esi |
@@: |
pop eax |
pop esi ebp |
ret |
fat_time_to_bdfe: |
; in: eax=FAT time |
; out: eax=BDFE time |
push ecx edx |
mov ecx, eax |
mov edx, eax |
shr eax, 11 |
shl eax, 16 ; hours |
and edx, 0x1F |
add edx, edx |
mov al, dl ; seconds |
shr ecx, 5 |
and ecx, 0x3F |
mov ah, cl ; minutes |
pop edx ecx |
ret |
fat_date_to_bdfe: |
push ecx edx |
mov ecx, eax |
mov edx, eax |
shr eax, 9 |
add ax, 1980 |
shl eax, 16 ; year |
and edx, 0x1F |
mov al, dl ; day |
shr ecx, 5 |
and ecx, 0xF |
mov ah, cl ; month |
pop edx ecx |
ret |
bdfe_to_fat_time: |
push edx |
mov edx, eax |
shr eax, 16 |
and dh, 0x3F |
shl eax, 6 |
or al, dh |
shr dl, 1 |
and dl, 0x1F |
shl eax, 5 |
or al, dl |
pop edx |
ret |
bdfe_to_fat_date: |
push edx |
mov edx, eax |
shr eax, 16 |
sub ax, 1980 |
and dh, 0xF |
shl eax, 4 |
or al, dh |
and dl, 0x1F |
shl eax, 5 |
or al, dl |
pop edx |
ret |
fat_entry_to_bdfe: |
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi |
; destroys eax |
mov eax, [ebp-4] |
mov [esi+4], eax ; ASCII/UNICODE name |
fat_entry_to_bdfe2: |
movzx eax, byte [edi+11] |
mov [esi], eax ; attributes |
movzx eax, word [edi+14] |
call fat_time_to_bdfe |
mov [esi+8], eax ; creation time |
movzx eax, word [edi+16] |
call fat_date_to_bdfe |
mov [esi+12], eax ; creation date |
and dword [esi+16], 0 ; last access time is not supported on FAT |
movzx eax, word [edi+18] |
call fat_date_to_bdfe |
mov [esi+20], eax ; last access date |
movzx eax, word [edi+22] |
call fat_time_to_bdfe |
mov [esi+24], eax ; last write time |
movzx eax, word [edi+24] |
call fat_date_to_bdfe |
mov [esi+28], eax ; last write date |
mov eax, [edi+28] |
mov [esi+32], eax ; file size (low dword) |
xor eax, eax |
mov [esi+36], eax ; file size (high dword) |
test ebp, ebp |
jz .ret |
push ecx edi |
lea edi, [esi+40] |
mov esi, ebp |
test byte [esi-4], 1 |
jz .ansi |
mov ecx, 260/2 |
rep movsd |
mov [edi-2], ax |
@@: |
mov esi, edi |
pop edi ecx |
.ret: |
ret |
.ansi: |
mov ecx, 264/4 |
rep movsd |
mov [edi-1], al |
jmp @b |
bdfe_to_fat_entry: |
; convert BDFE at edx to FAT entry at edi |
; destroys eax |
; attributes byte |
test byte [edi+11], 8 ; volume label? |
jnz @f |
mov al, [edx] |
and al, 0x27 |
and byte [edi+11], 0x10 |
or byte [edi+11], al |
@@: |
mov eax, [edx+8] |
call bdfe_to_fat_time |
mov [edi+14], ax ; creation time |
mov eax, [edx+12] |
call bdfe_to_fat_date |
mov [edi+16], ax ; creation date |
mov eax, [edx+20] |
call bdfe_to_fat_date |
mov [edi+18], ax ; last access date |
mov eax, [edx+24] |
call bdfe_to_fat_time |
mov [edi+22], ax ; last write time |
mov eax, [edx+28] |
call bdfe_to_fat_date |
mov [edi+24], ax ; last write date |
ret |
ramdisk_root_first: |
mov edi, RAMDISK+512*19 |
clc |
ret |
ramdisk_root_next: |
add edi, 0x20 |
cmp edi, RAMDISK+512*33 |
cmc |
ret |
ramdisk_root_extend_dir: |
stc |
ret |
uglobal |
; this is for delete support |
rd_prev_sector dd ? |
rd_prev_prev_sector dd ? |
endg |
ramdisk_notroot_next: |
add edi, 0x20 |
test edi, 0x1FF |
jz ramdisk_notroot_next_sector |
ret ; CF=0 |
ramdisk_notroot_next_sector: |
push ecx |
mov ecx, [eax] |
push [rd_prev_sector] |
pop [rd_prev_prev_sector] |
mov [rd_prev_sector], ecx |
mov ecx, [ecx*2+RAMDISK_FAT] |
and ecx, 0xFFF |
cmp ecx, 2849 |
jae ramdisk_notroot_first.err2 |
mov [eax], ecx |
pop ecx |
ramdisk_notroot_first: |
mov eax, [eax] |
cmp eax, 2 |
jb .err |
cmp eax, 2849 |
jae .err |
shl eax, 9 |
lea edi, [eax+(31 shl 9)+RAMDISK] |
clc |
ret |
.err2: |
pop ecx |
.err: |
stc |
ret |
ramdisk_notroot_next_write: |
test edi, 0x1FF |
jz ramdisk_notroot_next_sector |
ramdisk_root_next_write: |
ret |
ramdisk_notroot_extend_dir: |
pusha |
xor eax, eax |
mov edi, RAMDISK_FAT |
mov ecx, 2849 |
repnz scasw |
jnz .notfound |
mov word [edi-2], 0xFFF |
sub edi, RAMDISK_FAT |
shr edi, 1 |
dec edi |
mov eax, [esp+28] |
mov ecx, [eax] |
mov [RAMDISK_FAT+ecx*2], di |
mov [eax], edi |
shl edi, 9 |
add edi, (31 shl 9)+RAMDISK |
mov [esp], edi |
xor eax, eax |
mov ecx, 128 |
rep stosd |
popa |
clc |
ret |
.notfound: |
popa |
stc |
ret |
rd_find_lfn: |
; in: esi+ebp -> name |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry |
push esi edi |
push 0 |
push ramdisk_root_first |
push ramdisk_root_next |
.loop: |
call fat_find_lfn |
jc .notfound |
cmp byte [esi], 0 |
jz .found |
.continue: |
test byte [edi+11], 10h |
jz .notfound |
movzx eax, word [edi+26] |
mov [esp+8], eax |
mov dword [esp+4], ramdisk_notroot_first |
mov dword [esp], ramdisk_notroot_next |
test eax, eax |
jnz .loop |
mov dword [esp+4], ramdisk_root_first |
mov dword [esp], ramdisk_notroot_next |
jmp .loop |
.notfound: |
add esp, 12 |
pop edi esi |
stc |
ret |
.found: |
test ebp, ebp |
jz @f |
mov esi, ebp |
xor ebp, ebp |
jmp .continue |
@@: |
mov eax, [esp+8] |
add esp, 16 ; CF=0 |
pop esi |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskRead - LFN variant for reading sys floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskRead: |
cmp byte [esi], 0 |
jnz @f |
or ebx, -1 |
mov eax, 10 ; access denied |
ret |
@@: |
push edi |
call rd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, 5 ; file not found |
ret |
.found: |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
xor ebx, ebx |
.reteof: |
mov eax, 6 ; EOF |
pop edi |
ret |
@@: |
mov ebx, [ebx] |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+28] |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
jae @f |
mov ecx, eax |
mov byte [esp], 6 ; EOF |
@@: |
movzx edi, word [edi+26] ; cluster |
.new: |
jecxz .done |
test edi, edi |
jz .eof |
cmp edi, 0xFF8 |
jae .eof |
lea eax, [edi+31] ; bootsector+2*fat+filenames |
shl eax, 9 ; *512 |
add eax, RAMDISK ; image base |
; now eax points to data of cluster |
sub ebx, 512 |
jae .skip |
lea eax, [eax+ebx+512] |
neg ebx |
push ecx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
mov ebx, edx |
call memmove |
add edx, ecx |
sub [esp], ecx |
pop ecx |
xor ebx, ebx |
.skip: |
movzx edi, word [edi*2+RAMDISK_FAT] ; find next cluster from FAT |
jmp .new |
.eof: |
mov ebx, edx |
pop eax edx ecx |
sub ebx, edx |
jmp .reteof |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskReadFolder - LFN variant for reading sys floppy folder |
; |
; esi points to filename; only root is folder on ramdisk |
; ebx pointer to structure 32-bit number = first wanted block |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = size or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskReadFolder: |
push edi |
cmp byte [esi], 0 |
jz .root |
call rd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
test byte [edi+11], 0x10 |
jnz .found_dir |
pop edi |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
movzx eax, word [edi+26] |
add eax, 31 |
push 0 |
jmp .doit |
.root: |
mov eax, 19 |
push 14 |
.doit: |
push esi ecx ebp |
sub esp, 262*2 ; reserve space for LFN |
mov ebp, esp |
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names |
mov ebx, [ebx] |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
mov byte [edx], 1 ; version |
pop ecx eax |
mov esi, edi ; esi points to block of data of folder entry (BDFE) |
.main_loop: |
mov edi, eax |
shl edi, 9 |
add edi, RAMDISK |
push eax |
.l1: |
call fat_get_name |
jc .l2 |
cmp byte [edi+11], 0xF |
jnz .do_bdfe |
add edi, 0x20 |
test edi, 0x1FF |
jnz .do_bdfe |
pop eax |
inc eax |
dec byte [esp+262*2+16] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+RAMDISK_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+16], 0 |
@@: |
mov edi, eax |
shl edi, 9 |
add edi, RAMDISK |
push eax |
.do_bdfe: |
inc dword [edx+8] ; new file found |
dec ebx |
jns .l2 |
dec ecx |
js .l2 |
inc dword [edx+4] ; new file block copied |
call fat_entry_to_bdfe |
.l2: |
add edi, 0x20 |
test edi, 0x1FF |
jnz .l1 |
pop eax |
inc eax |
dec byte [esp+262*2+16] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+RAMDISK_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+16], 0 |
@@: |
jmp .main_loop |
.done: |
add esp, 262*2+4 |
pop ebp |
mov ebx, [edx+4] |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
pop ecx esi edi edi |
ret |
iglobal |
label fat_legal_chars byte |
; 0 = not allowed |
; 1 = allowed only in long names |
; 3 = allowed |
times 32 db 0 |
; ! " # $ % & ' ( ) * + , - . / |
db 1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0 |
; 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
db 3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0 |
; @ A B C D E F G H I J K L M N O |
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 |
; P Q R S T U V W X Y Z [ \ ] ^ _ |
db 3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3 |
; ` a b c d e f g h i j k l m n o |
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 |
; p q r s t u v w x y z { | } ~ |
db 3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0 |
endg |
fat_name_is_legal: |
; in: esi->(long) name |
; out: CF set <=> legal |
; destroys eax |
push esi |
xor eax, eax |
@@: |
lodsb |
test al, al |
jz .done |
cmp al, 80h |
jae .big |
test [fat_legal_chars+eax], 1 |
jnz @b |
.err: |
pop esi |
clc |
ret |
.big: |
; 0x80-0xAF, 0xE0-0xEF |
cmp al, 0xB0 |
jb @b |
cmp al, 0xE0 |
jb .err |
cmp al, 0xF0 |
jb @b |
jmp .err |
.done: |
sub esi, [esp] |
cmp esi, 257 |
pop esi |
ret |
fat_next_short_name: |
; in: edi->8+3 name |
; out: name corrected |
; CF=1 <=> error |
pushad |
mov ecx, 8 |
mov al, '~' |
std |
push edi |
add edi, 7 |
repnz scasb |
pop edi |
cld |
jz .tilde |
; tilde is not found, insert "~1" at end |
add edi, 6 |
cmp word [edi], ' ' |
jnz .insert_tilde |
@@: dec edi |
cmp byte [edi], ' ' |
jz @b |
inc edi |
.insert_tilde: |
mov word [edi], '~1' |
popad |
clc |
ret |
.tilde: |
push edi |
add edi, 7 |
xor ecx, ecx |
@@: |
; after tilde may be only digits and trailing spaces |
cmp byte [edi], '~' |
jz .break |
cmp byte [edi], ' ' |
jz .space |
cmp byte [edi], '9' |
jnz .found |
dec edi |
jmp @b |
.space: |
dec edi |
inc ecx |
jmp @b |
.found: |
inc byte [edi] |
add dword [esp], 8 |
jmp .zerorest |
.break: |
jecxz .noplace |
inc edi |
mov al, '1' |
@@: |
xchg al, [edi] |
inc edi |
cmp al, ' ' |
mov al, '0' |
jnz @b |
.succ: |
pop edi |
popad |
clc |
ret |
.noplace: |
dec edi |
cmp edi, [esp] |
jz .err |
add dword [esp], 8 |
mov word [edi], '~1' |
inc edi |
inc edi |
@@: |
mov byte [edi], '0' |
.zerorest: |
inc edi |
cmp edi, [esp] |
jb @b |
pop edi |
popad |
;clc ; automatically |
ret |
.err: |
pop edi |
popad |
stc |
ret |
fat_gen_short_name: |
; in: esi->long name |
; edi->buffer (8+3=11 chars) |
; out: buffer filled |
pushad |
mov eax, ' ' |
push edi |
stosd |
stosd |
stosd |
pop edi |
xor eax, eax |
push 8 |
pop ebx |
lea ecx, [edi+8] |
.loop: |
lodsb |
test al, al |
jz .done |
call char_toupper |
cmp al, ' ' |
jz .space |
cmp al, 80h |
ja .big |
test [fat_legal_chars+eax], 2 |
jnz .symbol |
.inv_symbol: |
mov al, '_' |
or bh, 1 |
.symbol: |
cmp al, '.' |
jz .dot |
.normal_symbol: |
dec bl |
jns .store |
mov bl, 0 |
.space: |
or bh, 1 |
jmp .loop |
.store: |
stosb |
jmp .loop |
.big: |
cmp al, 0xB0 |
jb .normal_symbol |
cmp al, 0xE0 |
jb .inv_symbol |
cmp al, 0xF0 |
jb .normal_symbol |
jmp .inv_symbol |
.dot: |
test bh, 2 |
jz .firstdot |
pop ebx |
add ebx, edi |
sub ebx, ecx |
push ebx |
cmp ebx, ecx |
jb @f |
pop ebx |
push ecx |
@@: |
cmp edi, ecx |
jbe .skip |
@@: |
dec edi |
mov al, [edi] |
dec ebx |
mov [ebx], al |
mov byte [edi], ' ' |
cmp edi, ecx |
ja @b |
.skip: |
mov bh, 3 |
jmp @f |
.firstdot: |
cmp bl, 8 |
jz .space |
push edi |
or bh, 2 |
@@: |
mov edi, ecx |
mov bl, 3 |
jmp .loop |
.done: |
test bh, 2 |
jz @f |
pop edi |
@@: |
lea edi, [ecx-8] |
test bh, 1 |
jz @f |
call fat_next_short_name |
@@: |
popad |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskRewrite - LFN variant for writing ramdisk |
; fs_RamdiskCreateFolder - create folder on ramdisk |
; |
; esi points to file/folder name |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ (ignored for folders) |
; edx mem location to data (ignored for folders) |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
fs_RamdiskCreateFolder: |
mov al, 1 ; create folder |
jmp fs_RamdiskRewrite.common |
fs_RamdiskRewrite: |
xor eax, eax ; create file |
.common: |
cmp byte [esi], 0 |
jz @b |
pushad |
xor edi, edi |
push esi |
test ebp, ebp |
jz @f |
mov esi, ebp |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
lea edi, [esi-1] |
jmp @b |
@@: |
pop esi |
test edi, edi |
jnz .noroot |
test ebp, ebp |
jnz .hasebp |
push ramdisk_root_extend_dir |
push ramdisk_root_next_write |
push edi |
push ramdisk_root_first |
push ramdisk_root_next |
jmp .common1 |
.hasebp: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [ebp], 0 |
jz .ret1 |
push ebp |
xor ebp, ebp |
call rd_find_lfn |
pop esi |
jc .notfound0 |
jmp .common0 |
.noroot: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [edi+1], 0 |
jz .ret1 |
; check existence |
mov byte [edi], 0 |
push edi |
call rd_find_lfn |
pop esi |
mov byte [esi], '/' |
jnc @f |
.notfound0: |
mov eax, ERROR_FILE_NOT_FOUND |
.ret1: |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
@@: |
inc esi |
.common0: |
test byte [edi+11], 0x10 ; must be directory |
mov eax, ERROR_ACCESS_DENIED |
jz .ret1 |
movzx ebp, word [edi+26] ; ebp=cluster |
mov eax, ERROR_FAT_TABLE |
cmp ebp, 2 |
jb .ret1 |
cmp ebp, 2849 |
jae .ret1 |
push ramdisk_notroot_extend_dir |
push ramdisk_notroot_next_write |
push ebp |
push ramdisk_notroot_first |
push ramdisk_notroot_next |
.common1: |
call fat_find_lfn |
jc .notfound |
; found |
test byte [edi+11], 10h |
jz .exists_file |
; found directory; if we are creating directory, return OK, |
; if we are creating file, say "access denied" |
add esp, 20 |
popad |
test al, al |
mov eax, ERROR_ACCESS_DENIED |
jz @f |
mov al, 0 |
@@: |
xor ebx, ebx |
ret |
.exists_file: |
; found file; if we are creating directory, return "access denied", |
; if we are creating file, delete existing file and continue |
cmp byte [esp+20+28], 0 |
jz @f |
add esp, 20 |
popad |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
@@: |
; delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xchg ax, word [edi+26] ; start cluster |
test eax, eax |
jz .done1 |
@@: |
cmp eax, 0xFF8 |
jae .done1 |
lea edi, [RAMDISK_FAT + eax*2] ; position in FAT |
xor eax, eax |
xchg ax, [edi] |
jmp @b |
.done1: |
pop edi |
call get_time_for_file |
mov [edi+22], ax |
call get_date_for_file |
mov [edi+24], ax |
mov [edi+18], ax |
or byte [edi+11], 20h ; set 'archive' attribute |
jmp .doit |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
add esp, 20 |
popad |
mov eax, ERROR_FILE_NOT_FOUND |
xor ebx, ebx |
ret |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi edi ecx |
mov esi, edi |
lea eax, [esp+12+12+8] |
mov [eax], ebp |
call dword [eax-4] |
jc .found |
.test_short_name_entry: |
cmp byte [edi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
lea eax, [esp+12+12+8] |
call dword [eax-8] |
jnc .test_short_name_entry |
jmp .found |
.short_name_found: |
pop ecx edi esi |
call fat_next_short_name |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12+20 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
pop ecx edi esi |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
; find <eax> successive entries in directory |
xor ecx, ecx |
push eax |
lea eax, [esp+12+8+12+8] |
mov [eax], ebp |
call dword [eax-4] |
pop eax |
.scan_dir: |
cmp byte [edi], 0 |
jz .free |
cmp byte [edi], 0xE5 |
jz .free |
xor ecx, ecx |
.scan_cont: |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax-8] |
pop eax |
jnc .scan_dir |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax+8] ; extend directory |
pop eax |
jnc .scan_dir |
add esp, 8+8+12+20 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.free: |
test ecx, ecx |
jnz @f |
mov [esp], edi |
mov ecx, [esp+8+8+12+8] |
mov [esp+4], ecx |
xor ecx, ecx |
@@: |
inc ecx |
cmp ecx, eax |
jb .scan_cont |
; found! |
; calculate name checksum |
push esi ecx |
mov esi, [esp+8+8] |
mov ecx, 11 |
xor eax, eax |
@@: |
ror al, 1 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
pop edi |
pop dword [esp+8+12+8] |
; edi points to last entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push eax |
mov al, 40h |
.writelfn: |
or al, cl |
mov esi, [esp+4] |
push ecx |
dec ecx |
imul ecx, 13 |
add esi, ecx |
stosb |
mov cl, 5 |
call .read_symbols |
mov ax, 0xF |
stosw |
mov al, [esp+4] |
stosb |
mov cl, 6 |
call .read_symbols |
xor eax, eax |
stosw |
mov cl, 2 |
call .read_symbols |
pop ecx |
lea eax, [esp+8+8+12+8] |
call dword [eax+4] ; next write |
xor eax, eax |
loop .writelfn |
pop eax |
pop esi |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
rep movsb |
mov word [edi], 20h ; attributes |
sub edi, 11 |
pop esi ecx |
add esp, 12 |
mov byte [edi+13], 0 ; tenths of a second at file creation time |
call get_time_for_file |
mov [edi+14], ax ; creation time |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+16], ax ; creation date |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
and word [edi+20], 0 ; high word of cluster |
and word [edi+26], 0 ; low word of cluster - to be filled |
and dword [edi+28], 0 ; file size - to be filled |
cmp byte [esp+20+28], 0 |
jz .doit |
; create directory |
mov byte [edi+11], 10h ; attributes: folder |
mov ecx, 32*2 |
mov edx, edi |
.doit: |
push edx |
push ecx |
push edi |
add edi, 26 ; edi points to low word of cluster |
push edi |
jecxz .done |
mov ecx, 2849 |
mov edi, RAMDISK_FAT |
.write_loop: |
; allocate new cluster |
xor eax, eax |
repnz scasw |
jnz .disk_full2 |
dec edi |
dec edi |
; lea eax, [edi-(RAMDISK_FAT)] |
mov eax, edi |
sub eax, RAMDISK_FAT |
shr eax, 1 ; eax = cluster |
mov word [edi], 0xFFF ; mark as last cluster |
xchg edi, [esp] |
stosw |
pop edi |
push edi |
inc ecx |
; write data |
cmp byte [esp+16+20+28], 0 |
jnz .writedir |
shl eax, 9 |
add eax, RAMDISK+31*512 |
.writefile: |
mov ebx, edx |
xchg eax, ebx |
push ecx |
mov ecx, 512 |
cmp dword [esp+12], ecx |
jae @f |
mov ecx, [esp+12] |
@@: |
call memmove |
add edx, ecx |
sub [esp+12], ecx |
pop ecx |
jnz .write_loop |
.done: |
mov ebx, edx |
pop edi edi ecx edx |
sub ebx, edx |
mov [edi+28], ebx |
add esp, 20 |
mov [esp+16], ebx |
popad |
xor eax, eax |
ret |
.disk_full2: |
mov ebx, edx |
pop edi edi ecx edx |
sub ebx, edx |
mov [edi+28], ebx |
add esp, 20 |
mov [esp+16], ebx |
popad |
push ERROR_DISK_FULL |
pop eax |
ret |
.writedir: |
mov edi, eax |
shl edi, 9 |
add edi, RAMDISK+31*512 |
mov esi, edx |
mov ecx, 32/4 |
push ecx |
rep movsd |
mov dword [edi-32], '. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
mov word [edi-32+26], ax |
mov esi, edx |
pop ecx |
rep movsd |
mov dword [edi-32], '.. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
mov eax, [esp+16+8] |
mov word [edi-32+26], ax |
xor eax, eax |
mov ecx, (512-32*2)/4 |
rep stosd |
pop edi edi ecx edx |
add esp, 20 |
popad |
xor eax, eax |
xor ebx, ebx |
ret |
.read_symbol: |
or ax, -1 |
test esi, esi |
jz .retFFFF |
lodsb |
test al, al |
jnz ansi2uni_char |
xor eax, eax |
xor esi, esi |
.retFFFF: |
ret |
.read_symbols: |
call .read_symbol |
stosw |
loop .read_symbols |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskWrite - LFN variant for writing to sys floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = bytes written (maybe 0) |
; eax = 0 ok write or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
push ERROR_ACCESS_DENIED |
fs_RamdiskWrite.ret0: |
pop eax |
xor ebx, ebx |
ret |
fs_RamdiskWrite: |
cmp byte [esi], 0 |
jz @b |
pushad |
call rd_find_lfn |
jnc .found |
popad |
push ERROR_FILE_NOT_FOUND |
jmp .ret0 |
.found: |
; must not be directory |
test byte [edi+11], 10h |
jz @f |
popad |
push ERROR_ACCESS_DENIED |
jmp .ret0 |
@@: |
; FAT does not support files larger than 4GB |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
.eof: |
popad |
push ERROR_END_OF_FILE |
jmp .ret0 |
@@: |
mov ebx, [ebx] |
.l1: |
; now edi points to direntry, ebx=start byte to write, |
; ecx=number of bytes to write, edx=data pointer |
call fat_update_datetime |
; extend file if needed |
add ecx, ebx |
jc .eof ; FAT does not support files larger than 4GB |
push 0 ; return value=0 |
cmp ecx, [edi+28] |
jbe .length_ok |
cmp ecx, ebx |
jz .length_ok |
call ramdisk_extend_file |
jnc .length_ok |
; ramdisk_extend_file can return two error codes: FAT table error or disk full. |
; First case is fatal error, in second case we may write some data |
mov [esp], eax |
cmp al, ERROR_DISK_FULL |
jz .disk_full |
pop eax |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
.disk_full: |
; correct number of bytes to write |
mov ecx, [edi+28] |
cmp ecx, ebx |
ja .length_ok |
.ret: |
pop eax |
mov [esp+28], eax ; eax=return value |
sub edx, [esp+20] |
mov [esp+16], edx ; ebx=number of written bytes |
popad |
ret |
.length_ok: |
; now ebx=start pos, ecx=end pos, both lie inside file |
sub ecx, ebx |
jz .ret |
movzx edi, word [edi+26] ; starting cluster |
.write_loop: |
sub ebx, 0x200 |
jae .next_cluster |
push ecx |
neg ebx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
mov eax, edi |
shl eax, 9 |
add eax, RAMDISK+31*512+0x200 |
sub eax, ebx |
mov ebx, eax |
mov eax, edx |
call memmove |
xor ebx, ebx |
add edx, ecx |
sub [esp], ecx |
pop ecx |
jz .ret |
.next_cluster: |
movzx edi, word [edi*2+RAMDISK_FAT] |
jmp .write_loop |
ramdisk_extend_file.zero_size: |
xor eax, eax |
jmp ramdisk_extend_file.start_extend |
; extends file on ramdisk to given size, new data area is filled by 0 |
; in: edi->direntry, ecx=new size |
; out: CF=0 => OK, eax=0 |
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) |
ramdisk_extend_file: |
push ecx |
; find the last cluster of file |
movzx eax, word [edi+26] ; first cluster |
mov ecx, [edi+28] |
jecxz .zero_size |
@@: |
sub ecx, 0x200 |
jbe @f |
mov eax, [eax*2+RAMDISK_FAT] |
and eax, 0xFFF |
jz .fat_err |
cmp eax, 0xFF8 |
jb @b |
.fat_err: |
pop ecx |
push ERROR_FAT_TABLE |
pop eax |
stc |
ret |
@@: |
push eax |
mov eax, [eax*2+RAMDISK_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
pop eax |
jb .fat_err |
; set length to full number of sectors and make sure that last sector is zero-padded |
sub [edi+28], ecx |
push eax edi |
mov edi, eax |
shl edi, 9 |
lea edi, [edi+RAMDISK+31*512+0x200+ecx] |
neg ecx |
xor eax, eax |
rep stosb |
pop edi eax |
.start_extend: |
pop ecx |
; now do extend |
push edx esi |
mov esi, RAMDISK_FAT+2*2 ; start scan from cluster 2 |
mov edx, 2847 ; number of clusters to scan |
.extend_loop: |
cmp [edi+28], ecx |
jae .extend_done |
; add new sector |
push ecx |
mov ecx, edx |
push edi |
mov edi, esi |
jecxz .disk_full |
push eax |
xor eax, eax |
repnz scasw |
pop eax |
jnz .disk_full |
mov word [edi-2], 0xFFF |
mov esi, edi |
mov edx, ecx |
sub edi, RAMDISK_FAT |
shr edi, 1 |
dec edi ; now edi=new cluster |
test eax, eax |
jz .first_cluster |
mov [RAMDISK_FAT+eax*2], di |
jmp @f |
.first_cluster: |
pop eax ; eax->direntry |
push eax |
mov [eax+26], di |
@@: |
push edi |
shl edi, 9 |
add edi, RAMDISK+31*512 |
xor eax, eax |
mov ecx, 512/4 |
rep stosd |
pop eax ; eax=new cluster |
pop edi ; edi->direntry |
pop ecx ; ecx=required size |
add dword [edi+28], 0x200 |
jmp .extend_loop |
.extend_done: |
mov [edi+28], ecx |
pop esi edx |
xor eax, eax ; CF=0 |
ret |
.disk_full: |
pop edi ecx |
pop esi edx |
stc |
push ERROR_DISK_FULL |
pop eax |
ret |
fat_update_datetime: |
call get_time_for_file |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskSetFileEnd - set end of file on ramdisk |
; |
; esi points to filename |
; ebx points to 64-bit number = new file size |
; ecx ignored (reserved) |
; edx ignored (reserved) |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskSetFileEnd: |
cmp byte [esi], 0 |
jnz @f |
.access_denied: |
push ERROR_ACCESS_DENIED |
jmp .ret |
@@: |
push edi |
call rd_find_lfn |
jnc @f |
pop edi |
push ERROR_FILE_NOT_FOUND |
.ret: |
pop eax |
ret |
@@: |
; must not be directory |
test byte [edi+11], 10h |
jz @f |
pop edi |
jmp .access_denied |
@@: |
; file size must not exceed 4Gb |
cmp dword [ebx+4], 0 |
jz @f |
pop edi |
push ERROR_END_OF_FILE |
jmp .ret |
@@: |
; set file modification date/time to current |
call fat_update_datetime |
mov eax, [ebx] |
cmp eax, [edi+28] |
jb .truncate |
ja .expand |
pop edi |
xor eax, eax |
ret |
.expand: |
push ecx |
mov ecx, eax |
call ramdisk_extend_file |
pop ecx |
pop edi |
ret |
.truncate: |
mov [edi+28], eax |
push ecx |
movzx ecx, word [edi+26] |
test eax, eax |
jz .zero_size |
; find new last sector |
@@: |
sub eax, 0x200 |
jbe @f |
movzx ecx, word [RAMDISK_FAT+ecx*2] |
jmp @b |
@@: |
; zero data at the end of last sector |
push ecx |
mov edi, ecx |
shl edi, 9 |
lea edi, [edi+RAMDISK+31*512+eax+0x200] |
mov ecx, eax |
neg ecx |
xor eax, eax |
rep stosb |
pop ecx |
; terminate FAT chain |
lea ecx, [RAMDISK_FAT+ecx+ecx] |
push dword [ecx] |
mov word [ecx], 0xFFF |
pop ecx |
and ecx, 0xFFF |
jmp .delete |
.zero_size: |
and word [edi+26], 0 |
.delete: |
; delete FAT chain starting with ecx |
; mark all clusters as free |
cmp ecx, 0xFF8 |
jae .deleted |
lea ecx, [RAMDISK_FAT+ecx+ecx] |
push dword [ecx] |
and word [ecx], 0 |
pop ecx |
and ecx, 0xFFF |
jmp .delete |
.deleted: |
pop ecx |
pop edi |
xor eax, eax |
ret |
fs_RamdiskGetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call rd_find_lfn |
fs_GetFileInfo_finish: |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
push esi ebp |
xor ebp, ebp |
mov esi, edx |
and dword [esi+4], 0 |
call fat_entry_to_bdfe2 |
pop ebp esi |
pop edi |
xor eax, eax |
ret |
fs_RamdiskSetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call rd_find_lfn |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
call bdfe_to_fat_entry |
pop edi |
xor eax, eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskDelete - delete file or empty folder from ramdisk |
; |
; esi points to filename |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskDelete: |
cmp byte [esi], 0 |
jnz @f |
; cannot delete root! |
.access_denied: |
push ERROR_ACCESS_DENIED |
.pop_ret: |
pop eax |
ret |
@@: |
and [rd_prev_sector], 0 |
and [rd_prev_prev_sector], 0 |
push edi |
call rd_find_lfn |
jnc .found |
pop edi |
push ERROR_FILE_NOT_FOUND |
jmp .pop_ret |
.found: |
cmp dword [edi], '. ' |
jz .access_denied2 |
cmp dword [edi], '.. ' |
jz .access_denied2 |
test byte [edi+11], 10h |
jz .dodel |
; we can delete only empty folders! |
movzx eax, word [edi+26] |
push ebx |
mov ebx, eax |
shl ebx, 9 |
add ebx, RAMDISK + 31*0x200 + 2*0x20 |
.checkempty: |
cmp byte [ebx], 0 |
jz .empty |
cmp byte [ebx], 0xE5 |
jnz .notempty |
add ebx, 0x20 |
test ebx, 0x1FF |
jnz .checkempty |
movzx eax, word [RAMDISK_FAT + eax*2] |
test eax, eax |
jz .empty |
mov ebx, eax |
shl ebx, 9 |
add ebx, RAMDISK + 31*0x200 |
jmp .checkempty |
.notempty: |
pop ebx |
.access_denied2: |
pop edi |
jmp .access_denied |
.empty: |
pop ebx |
.dodel: |
movzx eax, word [edi+26] |
; delete folder entry |
mov byte [edi], 0xE5 |
; delete LFN (if present) |
.lfndel: |
test edi, 0x1FF |
jnz @f |
cmp [rd_prev_sector], 0 |
jz @f |
cmp [rd_prev_sector], -1 |
jz .lfndone |
mov edi, [rd_prev_sector] |
push [rd_prev_prev_sector] |
pop [rd_prev_sector] |
or [rd_prev_prev_sector], -1 |
shl edi, 9 |
add edi, RAMDISK + 31*0x200 + 0x200 |
@@: |
sub edi, 0x20 |
cmp byte [edi], 0xE5 |
jz .lfndone |
cmp byte [edi+11], 0xF |
jnz .lfndone |
mov byte [edi], 0xE5 |
jmp .lfndel |
.lfndone: |
; delete FAT chain |
test eax, eax |
jz .done |
lea eax, [RAMDISK_FAT + eax*2] |
push dword [eax] |
and word [eax], 0 |
pop eax |
and eax, 0xFFF |
jmp .lfndone |
.done: |
pop edi |
xor eax, eax |
ret |
; \end{diamond} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/blkdev/rdsave.inc |
---|
0,0 → 1,30 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
iglobal |
saverd_fileinfo: |
dd 2 ; subfunction: write |
dd 0 ; (reserved) |
dd 0 ; (reserved) |
dd 1440*1024 ; size 1440 Kb |
dd RAMDISK |
db 0 |
.name: |
dd ? |
endg |
sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only) |
call restorefatchain |
mov ebx, saverd_fileinfo |
mov [saverd_fileinfo.name], ecx |
pushad |
call file_system_lfn ;in ebx |
popad |
mov [esp+32], eax |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc |
---|
0,0 → 1,928 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
; Low-level driver for HDD access |
; DMA support by Mario79 |
; Access through BIOS by diamond |
align 4 |
hd_read: |
;----------------------------------------------------------- |
; input : eax = block to read |
; ebx = destination |
;----------------------------------------------------------- |
and [hd_error], 0 |
push ecx esi edi ; scan cache |
; mov ecx,cache_max ; entries in cache |
; mov esi,HD_CACHE+8 |
call calculate_cache |
add esi,8 |
mov edi,1 |
hdreadcache: |
cmp dword [esi+4],0 ; empty |
je nohdcache |
cmp [esi],eax ; correct sector |
je yeshdcache |
nohdcache: |
add esi,8 |
inc edi |
dec ecx |
jnz hdreadcache |
call find_empty_slot ; ret in edi |
cmp [hd_error],0 |
jne return_01 |
; Read through BIOS? |
cmp [hdpos], 0x80 |
jae .bios |
; DMA read is permitted if [allow_dma_access]=1 or 2 |
cmp [allow_dma_access], 2 |
ja .nodma |
cmp [dma_hdd], 1 |
jnz .nodma |
call hd_read_dma |
jmp @f |
.nodma: |
call hd_read_pio |
jmp @f |
.bios: |
call bd_read |
@@: |
cmp [hd_error], 0 |
jne return_01 |
; lea esi,[edi*8+HD_CACHE] |
; push eax |
call calculate_cache_1 |
lea esi,[edi*8+esi] |
; pop eax |
mov [esi],eax ; sector number |
mov dword [esi+4],1 ; hd read - mark as same as in hd |
yeshdcache: |
mov esi,edi |
shl esi,9 |
; add esi,HD_CACHE+65536 |
push eax |
call calculate_cache_2 |
add esi,eax |
pop eax |
mov edi,ebx |
mov ecx,512/4 |
cld |
rep movsd ; move data |
return_01: |
pop edi esi ecx |
ret |
align 4 |
hd_read_pio: |
push eax edx |
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_read_error |
cli |
xor eax,eax |
mov edx,[hdbase] |
inc edx |
out dx,al ; ATAFeatures ॣ¨áâà "®á®¡¥®á⥩" |
inc edx |
inc eax |
out dx,al ; ATASectorCount áçñâ稪 ᥪâ®à®¢ |
inc edx |
mov eax,[esp+4] |
out dx,al ; ATASectorNumber ॣ¨áâà ®¬¥à ᥪâ®à |
shr eax,8 |
inc edx |
out dx,al ; ATACylinder ®¬¥à 樫¨¤à (¬« ¤è¨© ¡ ©â) |
shr eax,8 |
inc edx |
out dx,al ; ®¬¥à 樫¨¤à (áâ à訩 ¡ ©â) |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,byte [hdid] |
add al,128+64+32 |
out dx,al ; ®¬¥à £®«®¢ª¨/®¬¥à ¤¨áª |
inc edx |
mov al,20h |
out dx,al ; ATACommand ॣ¨áâà ª®¬ ¤ |
sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jne hd_read_error |
cli |
push edi |
shl edi,9 |
; add edi,HD_CACHE+65536 |
push eax |
call calculate_cache_2 |
add edi,eax |
pop eax |
mov ecx,256 |
mov edx,[hdbase] |
cld |
rep insw |
pop edi |
sti |
pop edx eax |
ret |
disable_ide_int: |
; mov edx,[hdbase] |
; add edx,0x206 |
; mov al,2 |
; out dx,al |
cli |
ret |
enable_ide_int: |
; mov edx,[hdbase] |
; add edx,0x206 |
; mov al,0 |
; out dx,al |
sti |
ret |
align 4 |
hd_write: |
;----------------------------------------------------------- |
; input : eax = block |
; ebx = pointer to memory |
;----------------------------------------------------------- |
push ecx esi edi |
; check if the cache already has the sector and overwrite it |
; mov ecx,cache_max |
; mov esi,HD_CACHE+8 |
call calculate_cache |
add esi,8 |
mov edi,1 |
hdwritecache: |
cmp dword [esi+4],0 ; if cache slot is empty |
je not_in_cache_write |
cmp [esi],eax ; if the slot has the sector |
je yes_in_cache_write |
not_in_cache_write: |
add esi,8 |
inc edi |
dec ecx |
jnz hdwritecache |
; sector not found in cache |
; write the block to a new location |
call find_empty_slot ; ret in edi |
cmp [hd_error],0 |
jne hd_write_access_denied |
; lea esi,[edi*8+HD_CACHE] |
; push eax |
call calculate_cache_1 |
lea esi,[edi*8+esi] |
; pop eax |
mov [esi],eax ; sector number |
yes_in_cache_write: |
mov dword [esi+4],2 ; write - differs from hd |
shl edi,9 |
; add edi,HD_CACHE+65536 |
push eax |
call calculate_cache_2 |
add edi,eax |
pop eax |
mov esi,ebx |
mov ecx,512/4 |
cld |
rep movsd ; move data |
hd_write_access_denied: |
pop edi esi ecx |
ret |
align 4 |
cache_write_pio: |
; call disable_ide_int |
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_write_error |
cli |
xor eax,eax |
mov edx,[hdbase] |
inc edx |
out dx,al |
inc edx |
inc eax |
out dx,al |
inc edx |
mov eax,[esi] ; eax = sector to write |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,byte [hdid] |
add al,128+64+32 |
out dx,al |
inc edx |
mov al,30h |
out dx,al |
sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jne hd_write_error |
push ecx esi |
cli |
mov esi,edi |
shl esi,9 |
; add esi,HD_CACHE+65536 ; esi = from memory position |
push eax |
call calculate_cache_2 |
add esi,eax |
pop eax |
mov ecx,256 |
mov edx,[hdbase] |
cld |
rep outsw |
sti |
; call enable_ide_int |
pop esi ecx |
ret |
save_hd_wait_timeout: |
push eax |
mov eax,[timer_ticks] |
add eax,300 ; 3 sec timeout |
mov [hd_wait_timeout],eax |
pop eax |
ret |
align 4 |
check_hd_wait_timeout: |
push eax |
mov eax,[hd_wait_timeout] |
cmp [timer_ticks], eax |
jg hd_timeout_error |
pop eax |
mov [hd_error],0 |
ret |
;iglobal |
; hd_timeout_str db 'K : FS - HD timeout',0 |
; hd_read_str db 'K : FS - HD read error',0 |
; hd_write_str db 'K : FS - HD write error',0 |
; hd_lba_str db 'K : FS - HD LBA error',0 |
;endg |
hd_timeout_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_timeout_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD timeout\n" |
mov [hd_error],1 |
pop eax |
ret |
hd_read_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_read_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD read error\n" |
pop edx eax |
ret |
hd_write_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_write_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD write error\n" |
ret |
hd_write_error_dma: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi, hd_write_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD read error\n" |
pop esi |
ret |
hd_lba_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_lba_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD LBA error\n" |
jmp LBA_read_ret |
align 4 |
wait_for_hd_idle: |
push eax edx |
call save_hd_wait_timeout |
mov edx,[hdbase] |
add edx,0x7 |
wfhil1: |
call check_hd_wait_timeout |
cmp [hd_error],0 |
jne @f |
in al,dx |
test al,128 |
jnz wfhil1 |
@@: |
pop edx eax |
ret |
align 4 |
wait_for_sector_buffer: |
push eax edx |
mov edx,[hdbase] |
add edx,0x7 |
call save_hd_wait_timeout |
hdwait_sbuf: ; wait for sector buffer to be ready |
call check_hd_wait_timeout |
cmp [hd_error],0 |
jne @f |
in al,dx |
test al,8 |
jz hdwait_sbuf |
mov [hd_error],0 |
cmp [hd_setup],1 ; do not mark error for setup request |
je buf_wait_ok |
test al,1 ; previous command ended up with an error |
jz buf_wait_ok |
@@: |
mov [hd_error],1 |
buf_wait_ok: |
pop edx eax |
ret |
; \begin{Mario79} |
align 4 |
wait_for_sector_dma_ide0: |
push eax |
push edx |
call save_hd_wait_timeout |
.wait: |
call change_task |
cmp [irq14_func], hdd_irq14 |
jnz .done |
call check_hd_wait_timeout |
cmp [hd_error], 0 |
jz .wait |
mov [irq14_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
mov al, 0 |
out dx, al |
.done: |
pop edx |
pop eax |
ret |
align 4 |
wait_for_sector_dma_ide1: |
push eax |
push edx |
call save_hd_wait_timeout |
.wait: |
call change_task |
cmp [irq15_func], hdd_irq15 |
jnz .done |
call check_hd_wait_timeout |
cmp [hd_error], 0 |
jz .wait |
mov [irq15_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
add dx, 8 |
mov al, 0 |
out dx, al |
.done: |
pop edx |
pop eax |
ret |
iglobal |
align 4 |
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary |
IDE_descriptor_table: |
dd IDE_DMA |
dw 0x2000 |
dw 0x8000 |
dma_cur_sector dd not 40h |
dma_hdpos dd 0 |
irq14_func dd hdd_irq_null |
irq15_func dd hdd_irq_null |
endg |
uglobal |
; all uglobals are zeroed at boot |
dma_process dd 0 |
dma_slot_ptr dd 0 |
cache_chain_pos dd 0 |
cache_chain_ptr dd 0 |
cache_chain_size db 0 |
cache_chain_started db 0 |
dma_task_switched db 0 |
dma_hdd db 0 |
allow_dma_access db 0 |
endg |
align 4 |
hdd_irq14: |
pushfd |
cli |
pushad |
mov [irq14_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
mov al, 0 |
out dx, al |
; call update_counters |
; mov ebx, [dma_process] |
; cmp [CURRENT_TASK], ebx |
; jz .noswitch |
; mov [dma_task_switched], 1 |
; mov edi, [dma_slot_ptr] |
; mov eax, [CURRENT_TASK] |
; mov [dma_process], eax |
; mov eax, [TASK_BASE] |
; mov [dma_slot_ptr], eax |
; mov [CURRENT_TASK], ebx |
; mov [TASK_BASE], edi |
; mov byte [DONT_SWITCH], 1 |
; call do_change_task |
.noswitch: |
popad |
popfd |
align 4 |
hdd_irq_null: |
ret |
align 4 |
hdd_irq15: |
pushfd |
cli |
pushad |
mov [irq15_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
add dx, 8 |
mov al, 0 |
out dx, al |
; call update_counters |
; mov ebx, [dma_process] |
; cmp [CURRENT_TASK], ebx |
; jz .noswitch |
; mov [dma_task_switched], 1 |
; mov edi, [dma_slot_ptr] |
; mov eax, [CURRENT_TASK] |
; mov [dma_process], eax |
; mov eax, [TASK_BASE] |
; mov [dma_slot_ptr], eax |
; mov [CURRENT_TASK], ebx |
; mov [TASK_BASE], edi |
; mov byte [DONT_SWITCH], 1 |
; call do_change_task |
.noswitch: |
popad |
popfd |
ret |
align 4 |
hd_read_dma: |
push eax |
push edx |
mov edx,[dma_hdpos] |
cmp edx,[hdpos] |
jne .notread |
mov edx, [dma_cur_sector] |
cmp eax, edx |
jb .notread |
add edx, 15 |
cmp [esp+4], edx |
ja .notread |
mov eax, [esp+4] |
sub eax, [dma_cur_sector] |
shl eax, 9 |
add eax, (OS_BASE+IDE_DMA) |
push ecx esi edi |
mov esi, eax |
shl edi, 9 |
; add edi, HD_CACHE+0x10000 |
push eax |
call calculate_cache_2 |
add edi,eax |
pop eax |
mov ecx, 512/4 |
cld |
rep movsd |
pop edi esi ecx |
pop edx |
pop eax |
ret |
.notread: |
mov eax, IDE_descriptor_table |
mov dword [eax], IDE_DMA |
mov word [eax+4], 0x2000 |
sub eax, OS_BASE |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add edx, 8 |
@@: |
push edx |
add edx, 4 |
out dx, eax |
pop edx |
mov al, 0 |
out dx, al |
add edx, 2 |
mov al, 6 |
out dx, al |
call wait_for_hd_idle |
cmp [hd_error], 0 |
jnz hd_read_error |
call disable_ide_int |
xor eax, eax |
mov edx, [hdbase] |
inc edx |
out dx, al |
inc edx |
mov eax, 10h |
out dx, al |
inc edx |
mov eax, [esp+4] |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
and al, 0xF |
add al, byte [hdid] |
add al, 11100000b |
out dx, al |
inc edx |
mov al, 0xC8 |
out dx, al |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add dx, 8 |
@@: |
mov al, 9 |
out dx, al |
mov eax, [CURRENT_TASK] |
mov [dma_process], eax |
mov eax, [TASK_BASE] |
mov [dma_slot_ptr], eax |
cmp [hdbase], 0x1F0 |
jnz .ide1 |
mov [irq14_func], hdd_irq14 |
jmp @f |
.ide1: |
mov [irq15_func], hdd_irq15 |
@@: |
call enable_ide_int |
cmp [hdbase], 0x1F0 |
jnz .wait_ide1 |
call wait_for_sector_dma_ide0 |
jmp @f |
.wait_ide1: |
call wait_for_sector_dma_ide1 |
@@: |
cmp [hd_error], 0 |
jnz hd_read_error |
mov eax,[hdpos] |
mov [dma_hdpos],eax |
pop edx |
pop eax |
mov [dma_cur_sector], eax |
jmp hd_read_dma |
align 4 |
write_cache_sector: |
mov [cache_chain_size],1 |
mov [cache_chain_pos],edi |
write_cache_chain: |
cmp [hdpos], 0x80 |
jae bd_write_cache_chain |
push esi |
mov eax, IDE_descriptor_table |
mov edx,eax |
pusha |
mov esi,[cache_chain_pos] |
shl esi, 9 |
call calculate_cache_2 |
add esi,eax |
mov edi, (OS_BASE+IDE_DMA) |
mov dword [edx], IDE_DMA |
movzx ecx, [cache_chain_size] |
shl ecx, 9 |
mov word [edx+4], cx |
shr ecx,2 |
cld |
rep movsd |
popa |
sub eax, OS_BASE |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add edx, 8 |
@@: |
push edx |
add edx, 4 |
out dx, eax |
pop edx |
mov al, 0 |
out dx, al |
add edx, 2 |
mov al, 6 |
out dx, al |
call wait_for_hd_idle |
cmp [hd_error], 0 |
jnz hd_write_error_dma |
call disable_ide_int |
xor eax, eax |
mov edx, [hdbase] |
inc edx |
out dx, al |
inc edx |
mov al, [cache_chain_size] |
out dx, al |
inc edx |
mov esi, [cache_chain_ptr] |
mov eax, [esi] |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
and al, 0xF |
add al, byte [hdid] |
add al, 11100000b |
out dx, al |
inc edx |
mov al, 0xCA |
out dx, al |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add dx, 8 |
@@: |
mov al, 1 |
out dx, al |
mov eax, [CURRENT_TASK] |
mov [dma_process], eax |
mov eax, [TASK_BASE] |
mov [dma_slot_ptr], eax |
cmp [hdbase], 0x1F0 |
jnz .ide1 |
mov [irq14_func], hdd_irq14 |
jmp @f |
.ide1: |
mov [irq15_func], hdd_irq15 |
@@: |
call enable_ide_int |
mov [dma_cur_sector], not 0x40 |
cmp [hdbase], 0x1F0 |
jnz .wait_ide1 |
call wait_for_sector_dma_ide0 |
jmp @f |
.wait_ide1: |
call wait_for_sector_dma_ide1 |
@@: |
cmp [hd_error], 0 |
jnz hd_write_error_dma |
pop esi |
ret |
uglobal |
IDEContrRegsBaseAddr dw ? |
endg |
; \end{Mario79} |
; \begin{diamond} |
uglobal |
bios_hdpos dd 0 ; 0 is invalid value for [hdpos] |
bios_cur_sector dd ? |
bios_read_len dd ? |
endg |
bd_read: |
push eax |
push edx |
mov edx, [bios_hdpos] |
cmp edx, [hdpos] |
jne .notread |
mov edx, [bios_cur_sector] |
cmp eax, edx |
jb .notread |
add edx, [bios_read_len] |
dec edx |
cmp eax, edx |
ja .notread |
sub eax, [bios_cur_sector] |
shl eax, 9 |
add eax, (OS_BASE+0x9A000) |
push ecx esi edi |
mov esi, eax |
shl edi, 9 |
; add edi, HD_CACHE+0x10000 |
push eax |
call calculate_cache_2 |
add edi,eax |
pop eax |
mov ecx, 512/4 |
cld |
rep movsd |
pop edi esi ecx |
pop edx |
pop eax |
ret |
.notread: |
push ecx |
mov dl, 42h |
mov ecx, 16 |
call int13_call |
pop ecx |
test eax, eax |
jnz .v86err |
test edx, edx |
jz .readerr |
mov [bios_read_len], edx |
mov edx, [hdpos] |
mov [bios_hdpos], edx |
pop edx |
pop eax |
mov [bios_cur_sector], eax |
jmp bd_read |
.readerr: |
.v86err: |
mov [hd_error], 1 |
jmp hd_read_error |
bd_write_cache_chain: |
pusha |
mov esi, [cache_chain_pos] |
shl esi, 9 |
call calculate_cache_2 |
add esi, eax |
mov edi, OS_BASE + 0x9A000 |
movzx ecx, [cache_chain_size] |
push ecx |
shl ecx, 9-2 |
rep movsd |
pop ecx |
mov dl, 43h |
mov eax, [cache_chain_ptr] |
mov eax, [eax] |
call int13_call |
test eax, eax |
jnz .v86err |
cmp edx, ecx |
jnz .writeerr |
popa |
ret |
.v86err: |
.writeerr: |
popa |
mov [hd_error], 1 |
jmp hd_write_error |
uglobal |
int13_regs_in rb v86_regs.size |
int13_regs_out rb v86_regs.size |
endg |
int13_call: |
; Because this code uses fixed addresses, |
; it can not be run simultaniously by many threads. |
; In current implementation it is protected by common mutex 'hd1_status' |
mov word [OS_BASE + 510h], 10h ; packet length |
mov word [OS_BASE + 512h], cx ; number of sectors |
mov dword [OS_BASE + 514h], 9A000000h ; buffer 9A00:0000 |
mov dword [OS_BASE + 518h], eax |
and dword [OS_BASE + 51Ch], 0 |
push ebx ecx esi edi |
mov ebx, int13_regs_in |
mov edi, ebx |
mov ecx, v86_regs.size/4 |
xor eax, eax |
rep stosd |
mov byte [ebx+v86_regs.eax+1], dl |
mov eax, [hdpos] |
lea eax, [BiosDisksData+(eax-80h)*4] |
mov dl, [eax] |
mov byte [ebx+v86_regs.edx], dl |
movzx edx, byte [eax+1] |
; mov dl, 5 |
test edx, edx |
jnz .hasirq |
dec edx |
jmp @f |
.hasirq: |
pushad |
stdcall enable_irq, edx |
popad |
@@: |
mov word [ebx+v86_regs.esi], 510h |
mov word [ebx+v86_regs.ss], 9000h |
mov word [ebx+v86_regs.esp], 0A000h |
mov word [ebx+v86_regs.eip], 500h |
mov [ebx+v86_regs.eflags], 20200h |
mov esi, [sys_v86_machine] |
mov ecx, 0x502 |
call v86_start |
and [bios_hdpos], 0 |
pop edi esi ecx ebx |
movzx edx, byte [OS_BASE + 512h] |
test byte [int13_regs_out+v86_regs.eflags], 1 |
jnz @f |
mov edx, ecx |
@@: |
ret |
; \end{diamond} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/blkdev/cd_drv.inc |
---|
0,0 → 1,929 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;********************************************************** |
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ óñòðîéñòâîì ÑD (ATAPI) |
;********************************************************** |
; Àâòîð ÷àñòè èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷ |
; Àäàïòàöèÿ, äîðàáîòêà è ðàçðàáîòêà Mario79,<Lrz> |
; Ìàêñèìàëüíîå êîëè÷åñòâî ïîâòîðåíèé îïåðàöèè ÷òåíèÿ |
MaxRetr equ 10 |
; Ïðåäåëüíîå âðåìÿ îæèäàíèÿ ãîòîâíîñòè ê ïðèåìó êîìàíäû |
; (â òèêàõ) |
BSYWaitTime equ 1000 ;2 |
NoTickWaitTime equ 0xfffff |
CDBlockSize equ 2048 |
;******************************************** |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ Ñ ÏÎÂÒÎÐÀÌÈ * |
;* Ìíîãîêðàòíîå ïîâòîðåíèå ÷òåíèÿ ïðè ñáîÿõ * |
;******************************************** |
ReadCDWRetr: |
;----------------------------------------------------------- |
; input : eax = block to read |
; ebx = destination |
;----------------------------------------------------------- |
pushad |
mov eax,[CDSectorAddress] |
mov ebx,[CDDataBuf_pointer] |
call cd_calculate_cache |
xor edi,edi |
add esi,8 |
inc edi |
.hdreadcache: |
; cmp dword [esi+4],0 ; empty |
; je .nohdcache |
cmp [esi],eax ; correct sector |
je .yeshdcache |
.nohdcache: |
add esi,8 |
inc edi |
dec ecx |
jnz .hdreadcache |
call find_empty_slot_CD_cache ; ret in edi |
push edi |
push eax |
call cd_calculate_cache_2 |
shl edi,11 |
add edi,eax |
mov [CDDataBuf_pointer],edi |
pop eax |
pop edi |
call ReadCDWRetr_1 |
cmp [DevErrorCode],0 |
jne .exit |
mov [CDDataBuf_pointer],ebx |
call cd_calculate_cache_1 |
lea esi,[edi*8+esi] |
mov [esi],eax ; sector number |
; mov dword [esi+4],1 ; hd read - mark as same as in hd |
.yeshdcache: |
mov esi,edi |
shl esi,11 ;9 |
push eax |
call cd_calculate_cache_2 |
add esi,eax |
pop eax |
mov edi,ebx ;[CDDataBuf_pointer] |
mov ecx,512 ;/4 |
cld |
rep movsd ; move data |
.exit: |
popad |
ret |
ReadCDWRetr_1: |
pushad |
; Öèêë, ïîêà êîìàíäà íå âûïîëíåíà óñïåøíî èëè íå |
; èñ÷åðïàíî êîëè÷åñòâî ïîïûòîê |
mov ECX,MaxRetr |
@@NextRetr: |
; Ïîäàòü êîìàíäó |
;************************************************* |
;* ÏÎËÍÎÅ ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÊÎÌÏÀÊÒ-ÄÈÑÊÀ * |
;* Ñ÷èòûâàþòñÿ äàííûå ïîëüçîâàòåëÿ, èíôîðìàöèÿ * |
;* ñóáêàíàëà è êîíòðîëüíàÿ èíôîðìàöèÿ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* CDSectorAddress - àäðåñ ñ÷èòûâàåìîãî ñåêòîðà. * |
;* Äàííûå ñ÷èòûâàåòñÿ â ìàññèâ CDDataBuf. * |
;************************************************* |
;ReadCD: |
push ecx |
; pusha |
; Çàäàòü ðàçìåð ñåêòîðà |
; mov [CDBlockSize],2048 ;2352 |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ |
; ñåêòîðà äàííûõ |
; Çàäàòü êîä êîìàíäû Read CD |
mov [PacketCommand],byte 0x28 ;0xBE |
; Çàäàòü àäðåñ ñåêòîðà |
mov AX,word [CDSectorAddress+2] |
xchg AL,AH |
mov word [PacketCommand+2],AX |
mov AX,word [CDSectorAddress] |
xchg AL,AH |
mov word [PacketCommand+4],AX |
; mov eax,[CDSectorAddress] |
; mov [PacketCommand+2],eax |
; Çàäàòü êîëè÷åñòâî ñ÷èòûâàåìûõ ñåêòîðîâ |
mov [PacketCommand+8],byte 1 |
; Çàäàòü ñ÷èòûâàíèå äàííûõ â ïîëíîì îáúåìå |
; mov [PacketCommand+9],byte 0xF8 |
; Ïîäàòü êîìàíäó |
call SendPacketDatCommand |
pop ecx |
; ret |
; cmp [DevErrorCode],0 |
test eax,eax |
jz @@End_4 |
or ecx,ecx ;{SPraid.simba} (for cd load) |
jz @@End_4 |
dec ecx |
cmp [timer_ticks_enable],0 |
jne @f |
mov eax,NoTickWaitTime |
.wait: |
dec eax |
; test eax,eax |
jz @@NextRetr |
jmp .wait |
@@: |
; Çàäåðæêà íà 2,5 ñåêóíäû |
; mov EAX,[timer_ticks] |
; add EAX,50 ;250 |
;@@Wait: |
; call change_task |
; cmp EAX,[timer_ticks] |
; ja @@Wait |
loop @@NextRetr |
@@End_4: |
mov dword [DevErrorCode],eax |
popad |
ret |
; Óíèâåðñàëüíûå ïðîöåäóðû, îáåñïå÷èâàþùèå âûïîëíåíèå |
; ïàêåòíûõ êîìàíä â ðåæèìå PIO |
; Ìàêñèìàëüíî äîïóñòèìîå âðåìÿ îæèäàíèÿ ðåàêöèè |
; óñòðîéñòâà íà ïàêåòíóþ êîìàíäó (â òèêàõ) |
MaxCDWaitTime equ 1000 ;200 ;10 ñåêóíä |
uglobal |
; Îáëàñòü ïàìÿòè äëÿ ôîðìèðîâàíèÿ ïàêåòíîé êîìàíäû |
PacketCommand: rb 12 ;DB 12 DUP (?) |
; Îáëàñòü ïàìÿòè äëÿ ïðèåìà äàííûõ îò äèñêîâîäà |
;CDDataBuf DB 4096 DUP (0) |
; Ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ â áàéòàõ |
;CDBlockSize DW ? |
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà äàííûõ |
CDSectorAddress: DD ? |
; Âðåìÿ íà÷àëà î÷åðåäíîé îïåðàöèè ñ äèñêîì |
TickCounter_1 DD 0 |
; Âðåìÿ íà÷àëà îæèäàíèÿ ãîòîâíîñòè óñòðîéñòâà |
WURStartTime DD 0 |
; óêàçàòåëü áóôåðà äëÿ ñ÷èòûâàíèÿ |
CDDataBuf_pointer dd 0 |
endg |
;**************************************************** |
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, * |
;* ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×Ó ÎÄÍÎÃÎ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* ÐÀÇÌÅÐÎÌ 2048 ÁÀÉÒ ÎÒ ÓÑÒÐÎÉÑÒÂÀ Ê ÕÎÑÒÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò; * |
;* CDBlockSize - ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ. * |
; return eax DevErrorCode |
;**************************************************** |
SendPacketDatCommand: |
xor eax,eax |
; mov byte [DevErrorCode],al |
; Çàäàòü ðåæèì CHS |
mov byte [ATAAddressMode],al |
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû |
mov byte [ATAFeatures],al |
mov byte [ATASectorCount],al |
mov byte [ATASectorNumber],al |
; Çàãðóçèòü ðàçìåð ïåðåäàâàåìîãî áëîêà |
mov [ATAHead],al |
; mov AX,[CDBlockSize] |
mov [ATACylinder],CDBlockSize |
mov [ATACommand],0A0h |
call SendCommandToHDD_1 |
test eax,eax |
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
jnz @@End_8 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó |
; ïàêåòíîé êîìàíäû |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
mov ecx,NoTickWaitTime |
@@WaitDevice0: |
cmp [timer_ticks_enable],0 |
jne @f |
dec ecx |
; test ecx,ecx |
jz @@Err1_1 |
jmp .test |
@@: |
call change_task |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,BSYWaitTime |
ja @@Err1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
.test: |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice0 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice0 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6 |
; Ïîñëàòü ïàêåòíóþ êîìàíäó |
cli |
mov DX,[ATABasePortAddr] |
mov AX,[PacketCommand] |
out DX,AX |
mov AX,[PacketCommand+2] |
out DX,AX |
mov AX,[PacketCommand+4] |
out DX,AX |
mov AX,[PacketCommand+6] |
out DX,AX |
mov AX,[PacketCommand+8] |
out DX,AX |
mov AX,[PacketCommand+10] |
out DX,AX |
sti |
; Îæèäàíèå ãîòîâíîñòè äàííûõ |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
mov ecx,NoTickWaitTime |
@@WaitDevice1: |
cmp [timer_ticks_enable],0 |
jne @f |
dec ecx |
; test ecx,ecx |
jz @@Err1_1 |
jmp .test_1 |
@@: |
call change_task |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,MaxCDWaitTime |
ja @@Err1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
.test_1: |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice1 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_temp |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf |
; Çàãðóçèòü àäðåñ ðåãèñòðà äàííûõ êîíòðîëëåðà |
mov DX,[ATABasePortAddr] ;ïîðò 1x0h |
; Çàãðóçèòü â ñ÷åò÷èê ðàçìåð áëîêà â áàéòàõ |
xor ecx,ecx |
mov CX,CDBlockSize |
; Âû÷èñëèòü ðàçìåð áëîêà â 16-ðàçðÿäíûõ ñëîâàõ |
shr CX,1 ;ðàçäåëèòü ðàçìåð áëîêà íà 2 |
; Ïðèíÿòü áëîê äàííûõ |
cli |
cld |
rep insw |
sti |
; Óñïåøíîå çàâåðøåíèå ïðèåìà äàííûõ |
@@End_8: |
xor eax,eax |
ret |
; Çàïèñàòü êîä îøèáêè |
@@Err1_1: |
xor eax,eax |
inc eax |
ret |
; mov [DevErrorCode],1 |
; ret |
@@Err6_temp: |
mov eax,7 |
ret |
; mov [DevErrorCode],7 |
; ret |
@@Err6: |
mov eax,6 |
ret |
; mov [DevErrorCode],6 |
;@@End_8: |
; ret |
;*********************************************** |
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, * |
;* ÍÅ ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×È ÄÀÍÍÛÕ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç * |
;* ãëîáàëüíûå ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò. * |
;*********************************************** |
SendPacketNoDatCommand: |
pushad |
xor eax,eax |
; mov byte [DevErrorCode],al |
; Çàäàòü ðåæèì CHS |
mov byte [ATAAddressMode],al |
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû |
mov byte [ATAFeatures],al |
mov byte [ATASectorCount],al |
mov byte [ATASectorNumber],al |
mov word [ATACylinder],ax |
mov byte [ATAHead],al |
mov [ATACommand],0A0h |
call SendCommandToHDD_1 |
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
test eax,eax |
jnz @@End_9 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó |
; ïàêåòíîé êîìàíäû |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
@@WaitDevice0_1: |
call change_task |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,BSYWaitTime |
ja @@Err1_3 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice0_1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_1 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice0_1 |
; Ïîñëàòü ïàêåòíóþ êîìàíäó |
; cli |
mov DX,[ATABasePortAddr] |
mov AX,word [PacketCommand] |
out DX,AX |
mov AX,word [PacketCommand+2] |
out DX,AX |
mov AX,word [PacketCommand+4] |
out DX,AX |
mov AX,word [PacketCommand+6] |
out DX,AX |
mov AX,word [PacketCommand+8] |
out DX,AX |
mov AX,word [PacketCommand+10] |
out DX,AX |
; sti |
cmp [ignore_CD_eject_wait],1 |
je @@clear_DEC |
; Îæèäàíèå ïîäòâåðæäåíèÿ ïðèåìà êîìàíäû |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
@@WaitDevice1_1: |
call change_task |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,MaxCDWaitTime |
ja @@Err1_3 ;îøèáêà òàéì-àóòà |
; Îæèäàòü îñâîáîæäåíèÿ óñòðîéñòâà |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice1_1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_1 |
test AL,40h ;ñîñòîÿíèå ñèãíàëà DRDY |
jz @@WaitDevice1_1 |
@@clear_DEC: |
and [DevErrorCode],0 |
popad |
ret |
; Çàïèñàòü êîä îøèáêè |
@@Err1_3: |
xor eax,eax |
inc eax |
jmp @@End_9 |
@@Err6_1: |
mov eax,6 |
@@End_9: |
mov [DevErrorCode],eax |
popad |
ret |
;**************************************************** |
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1); * |
;* ATAFeatures - "îñîáåííîñòè"; * |
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; * |
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; * |
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; * |
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; * |
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); * |
;* ATACommand - êîä êîìàíäû. * |
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: * |
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; * |
;* â DevErrorCode - íîëü. * |
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò * |
;* âîçâðàùåí êîä îøèáêè â eax * |
;**************************************************** |
SendCommandToHDD_1: |
; pushad |
; mov [DevErrorCode],0 not need |
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà |
cmp [ATAAddressMode],1 |
ja @@Err2_4 |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
mov BX,[ChannelNumber] |
cmp BX,1 |
jb @@Err3_4 |
cmp BX,2 |
ja @@Err3_4 |
; Óñòàíîâèòü áàçîâûé àäðåñ |
dec BX |
shl BX,1 |
movzx ebx,bx |
mov AX,[ebx+StandardATABases] |
mov [ATABasePortAddr],AX |
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû |
; Âûáðàòü íóæíûé äèñê |
mov DX,[ATABasePortAddr] |
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê |
mov AL,[DiskNumber] |
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà |
ja @@Err4_4 |
shl AL,4 |
or AL,10100000b |
out DX,AL |
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ |
inc DX |
mov eax,[timer_ticks] |
mov [TickCounter_1],eax |
mov ecx,NoTickWaitTime |
@@WaitHDReady_2: |
cmp [timer_ticks_enable],0 |
jne @f |
dec ecx |
; test ecx,ecx |
jz @@Err1_4 |
jmp .test |
@@: |
call change_task |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ |
mov eax,[timer_ticks] |
sub eax,[TickCounter_1] |
cmp eax,BSYWaitTime ;300 ;îæèäàòü 3 ñåê. |
ja @@Err1_4 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ |
.test: |
in AL,DX |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
test AL,80h |
jnz @@WaitHDReady_2 |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ |
test AL,08h |
jnz @@WaitHDReady_2 |
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà |
cli |
mov DX,[ATABasePortAddr] |
inc DX ;ðåãèñòð "îñîáåííîñòåé" |
mov AL,[ATAFeatures] |
out DX,AL |
inc DX ;ñ÷åò÷èê ñåêòîðîâ |
mov AL,[ATASectorCount] |
out DX,AL |
inc DX ;ðåãèñòð íîìåðà ñåêòîðà |
mov AL,[ATASectorNumber] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò) |
mov AX,[ATACylinder] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò) |
mov AL,AH |
out DX,AL |
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà |
mov AL,[DiskNumber] |
shl AL,4 |
cmp [ATAHead],0Fh ;ïðîâåðèòü íîìåð ãîëîâêè |
ja @@Err5_4 |
or AL,[ATAHead] |
or AL,10100000b |
mov AH,[ATAAddressMode] |
shl AH,6 |
or AL,AH |
out DX,AL |
; Ïîñëàòü êîìàíäó |
mov AL,[ATACommand] |
inc DX ;ðåãèñòð êîìàíä |
out DX,AL |
sti |
; Ñáðîñèòü ïðèçíàê îøèáêè |
; mov [DevErrorCode],0 |
@@End_10: |
xor eax,eax |
ret |
; Çàïèñàòü êîä îøèáêè |
@@Err1_4: |
xor eax,eax |
inc eax |
; mov [DevErrorCode],1 |
ret |
@@Err2_4: |
mov eax,2 |
; mov [DevErrorCode],2 |
ret |
@@Err3_4: |
mov eax,3 |
; mov [DevErrorCode],3 |
ret |
@@Err4_4: |
mov eax,4 |
; mov [DevErrorCode],4 |
ret |
@@Err5_4: |
mov eax,5 |
; mov [DevErrorCode],5 |
; Çàâåðøåíèå ðàáîòû ïðîãðàììû |
ret |
; sti |
; popad |
;************************************************* |
;* ÎÆÈÄÀÍÈÅ ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ Ê ÐÀÁÎÒÅ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
WaitUnitReady: |
pusha |
; Çàïîìíèòü âðåìÿ íà÷àëà îïåðàöèè |
mov EAX,[timer_ticks] |
mov [WURStartTime],EAX |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü êîìàíäó TEST UNIT READY |
mov [PacketCommand],word 00h |
; ÖÈÊË ÎÆÈÄÀÍÈß ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ |
mov ecx,NoTickWaitTime |
@@SendCommand: |
; Ïîäàòü êîìàíäó ïðîâåðêè ãîòîâíîñòè |
call SendPacketNoDatCommand |
cmp [timer_ticks_enable],0 |
jne @f |
cmp [DevErrorCode],0 |
je @@End_11 |
dec ecx |
; cmp ecx,0 |
jz .Error |
jmp @@SendCommand |
@@: |
call change_task |
; Ïðîâåðèòü êîä îøèáêè |
cmp [DevErrorCode],0 |
je @@End_11 |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ ãîòîâíîñòè |
mov EAX,[timer_ticks] |
sub EAX,[WURStartTime] |
cmp EAX,MaxCDWaitTime |
jb @@SendCommand |
.Error: |
; Îøèáêà òàéì-àóòà |
mov [DevErrorCode],1 |
@@End_11: |
popa |
ret |
;************************************************* |
;* ÇÀÏÐÅÒÈÒÜ ÑÌÅÍÓ ÄÈÑÊÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
prevent_medium_removal: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],byte 0x1E |
; Çàäàòü êîä çàïðåòà |
mov [PacketCommand+4],byte 11b |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
mov eax,ATAPI_IDE0_lock |
add eax,[cdpos] |
dec eax |
mov [eax],byte 1 |
popa |
ret |
;************************************************* |
;* ÐÀÇÐÅØÈÒÜ ÑÌÅÍÓ ÄÈÑÊÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
allow_medium_removal: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],byte 0x1E |
; Çàäàòü êîä çàïðåòà |
mov [PacketCommand+4],byte 00b |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
mov eax,ATAPI_IDE0_lock |
add eax,[cdpos] |
dec eax |
mov [eax],byte 0 |
popa |
ret |
;************************************************* |
;* ÇÀÃÐÓÇÈÒÜ ÍÎÑÈÒÅËÜ Â ÄÈÑÊÎÂÎÄ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
LoadMedium: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],word 1Bh |
; Çàäàòü îïåðàöèþ çàãðóçêè íîñèòåëÿ |
mov [PacketCommand+4],word 00000011b |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
popa |
ret |
;************************************************* |
;* ÈÇÂËÅ×Ü ÍÎÑÈÒÅËÜ ÈÇ ÄÈÑÊÎÂÎÄÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
EjectMedium: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],word 1Bh |
; Çàäàòü îïåðàöèþ èçâëå÷åíèÿ íîñèòåëÿ |
mov [PacketCommand+4],word 00000010b |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
popa |
ret |
;************************************************* |
;* Ïðîâåðèòü ñîáûòèå íàæàòèÿ êíîïêè èçâëå÷åíèÿ * |
;* äèñêà * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
align 4 |
check_ATAPI_device_event: |
pusha |
mov eax,[timer_ticks] |
sub eax,[timer_ATAPI_check] |
cmp eax,100 |
jb .end_1 |
mov al,[DRIVE_DATA+1] |
and al,11b |
cmp al,10b |
jz .ide3 |
.ide2_1: |
mov al,[DRIVE_DATA+1] |
and al,1100b |
cmp al,1000b |
jz .ide2 |
.ide1_1: |
mov al,[DRIVE_DATA+1] |
and al,110000b |
cmp al,100000b |
jz .ide1 |
.ide0_1: |
mov al,[DRIVE_DATA+1] |
and al,11000000b |
cmp al,10000000b |
jz .ide0 |
.end: |
sti |
mov eax,[timer_ticks] |
mov [timer_ATAPI_check],eax |
.end_1: |
popa |
ret |
.ide3: |
cli |
cmp [ATAPI_IDE3_lock],1 |
jne .ide2_1 |
cmp [IDE_Channel_2],0 |
jne .ide1_1 |
cmp [cd_status],0 |
jne .end |
mov [IDE_Channel_2],1 |
call reserve_ok2 |
mov [ChannelNumber],2 |
mov [DiskNumber],1 |
mov [cdpos],4 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4],byte 1 |
je .eject_ide3 |
call syscall_cdaudio.free |
jmp .ide2_1 |
.eject_ide3: |
call .eject |
call syscall_cdaudio.free |
jmp .ide2_1 |
.ide2: |
cli |
cmp [ATAPI_IDE2_lock],1 |
jne .ide1_1 |
cmp [IDE_Channel_2],0 |
jne .ide1_1 |
cmp [cd_status],0 |
jne .end |
mov [IDE_Channel_2],1 |
call reserve_ok2 |
mov [ChannelNumber],2 |
mov [DiskNumber],0 |
mov [cdpos],3 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4],byte 1 |
je .eject_ide2 |
call syscall_cdaudio.free |
jmp .ide1_1 |
.eject_ide2: |
call .eject |
call syscall_cdaudio.free |
jmp .ide1_1 |
.ide1: |
cli |
cmp [ATAPI_IDE1_lock],1 |
jne .ide0_1 |
cmp [IDE_Channel_1],0 |
jne .end |
cmp [cd_status],0 |
jne .end |
mov [IDE_Channel_1],1 |
call reserve_ok2 |
mov [ChannelNumber],1 |
mov [DiskNumber],1 |
mov [cdpos],2 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4],byte 1 |
je .eject_ide1 |
call syscall_cdaudio.free |
jmp .ide0_1 |
.eject_ide1: |
call .eject |
call syscall_cdaudio.free |
jmp .ide0_1 |
.ide0: |
cli |
cmp [ATAPI_IDE0_lock],1 |
jne .end |
cmp [IDE_Channel_1],0 |
jne .end |
cmp [cd_status],0 |
jne .end |
mov [IDE_Channel_1],1 |
call reserve_ok2 |
mov [ChannelNumber],1 |
mov [DiskNumber],0 |
mov [cdpos],1 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4],byte 1 |
je .eject_ide0 |
call syscall_cdaudio.free |
jmp .end |
.eject_ide0: |
call .eject |
call syscall_cdaudio.free |
jmp .end |
.eject: |
call clear_CD_cache |
call allow_medium_removal |
mov [ignore_CD_eject_wait],1 |
call EjectMedium |
mov [ignore_CD_eject_wait],0 |
ret |
iglobal |
timer_ATAPI_check dd 0 |
ATAPI_IDE0_lock db 0 |
ATAPI_IDE1_lock db 0 |
ATAPI_IDE2_lock db 0 |
ATAPI_IDE3_lock db 0 |
ignore_CD_eject_wait db 0 |
endg |
;************************************************* |
;* Ïîëó÷èòü ñîîáùåíèå î ñîáûòèè èëè ñîñòîÿíèè * |
;* óñòðîéñòâà * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
GetEvent_StatusNotification: |
pusha |
mov [CDDataBuf_pointer],CDDataBuf |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],byte 4Ah |
mov [PacketCommand+1],byte 00000001b |
; Çàäàòü çàïðîñ êëàññà ñîîáùåíèé |
mov [PacketCommand+4],byte 00010000b |
; Ðàçìåð âûäåëåííîé îáëàñòè |
mov [PacketCommand+7],byte 8h |
mov [PacketCommand+8],byte 0h |
; Ïîäàòü êîìàíäó |
call SendPacketDatCommand |
popa |
ret |
;************************************************* |
; ïðî÷èòàòü èíôîðìàöèþ èç TOC |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
Read_TOC: |
pusha |
mov [CDDataBuf_pointer],CDDataBuf |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ |
; ñåêòîðà äàííûõ |
mov [PacketCommand],byte 0x43 |
; Çàäàòü ôîðìàò |
mov [PacketCommand+2],byte 1 |
; Ðàçìåð âûäåëåííîé îáëàñòè |
mov [PacketCommand+7],byte 0xFF |
mov [PacketCommand+8],byte 0h |
; Ïîäàòü êîìàíäó |
call SendPacketDatCommand |
popa |
ret |
;************************************************* |
;* ÎÏÐÅÄÅËÈÒÜ ÎÁÙÅÅ ÊÎËÈ×ÅÑÒÂÎ ÑÅÊÒÎÐΠÍÀ ÄÈÑÊÅ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
;ReadCapacity: |
; pusha |
;; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
; call clear_packet_buffer |
;; Çàäàòü ðàçìåð áóôåðà â áàéòàõ |
; mov [CDBlockSize],8 |
;; Ñôîðìèðîâàòü êîìàíäó READ CAPACITY |
; mov [PacketCommand],word 25h |
;; Ïîäàòü êîìàíäó |
; call SendPacketDatCommand |
; popa |
; ret |
clear_packet_buffer: |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
and [PacketCommand],dword 0 |
and [PacketCommand+4],dword 0 |
and [PacketCommand+8],dword 0 |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/blkdev/flp_drv.inc |
---|
0,0 → 1,626 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
;********************************************************** |
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ êîíòðîëëåðîì ãèáêîãî äèñêà |
;********************************************************** |
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Àäàïòàöèÿ è äîðàáîòêà Mario79 |
;give_back_application_data: ; ïåðåñëàòü ïðèëîæåíèþ |
; mov edi,[TASK_BASE] |
; mov edi,[edi+TASKDATA.mem_start] |
; add edi,ecx |
give_back_application_data_1: |
mov esi,FDD_BUFF ;FDD_DataBuffer ;0x40000 |
xor ecx,ecx |
mov cx,128 |
cld |
rep movsd |
ret |
;take_data_from_application: ; âçÿòü èç ïðèëîæåíè |
; mov esi,[TASK_BASE] |
; mov esi,[esi+TASKDATA.mem_start] |
; add esi,ecx |
take_data_from_application_1: |
mov edi,FDD_BUFF ;FDD_DataBuffer ;0x40000 |
xor ecx,ecx |
mov cx,128 |
cld |
rep movsd |
ret |
; Êîäû çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì (FDC_Status) |
FDC_Normal equ 0 ;íîðìàëüíîå çàâåðøåíèå |
FDC_TimeOut equ 1 ;îøèáêà òàéì-àóòà |
FDC_DiskNotFound equ 2 ;â äèñêîâîäå íåò äèñêà |
FDC_TrackNotFound equ 3 ;äîðîæêà íå íàéäåíà |
FDC_SectorNotFound equ 4 ;ñåêòîð íå íàéäåí |
; Ìàêñèìàëüíûå çíà÷åíèÿ êîîðäèíàò ñåêòîðà (çàäàííûå |
; çíà÷åíèÿ ñîîòâåòñòâóþò ïàðàìåòðàì ñòàíäàðòíîãî |
; òðåõäþéìîâîãî ãèáêîãî äèñêà îáúåìîì 1,44 Ìá) |
MAX_Track equ 79 |
MAX_Head equ 1 |
MAX_Sector equ 18 |
uglobal |
; Ñ÷åò÷èê òèêîâ òàéìåðà |
TickCounter dd ? |
; Êîä çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì ÍÃÌÄ |
FDC_Status DB ? |
; Ôëàã ïðåðûâàíèÿ îò ÍÃÌÄ |
FDD_IntFlag DB ? |
; Ìîìåíò íà÷àëà ïîñëåäíåé îïåðàöèè ñ ÍÃÌÄ |
FDD_Time DD ? |
; Íîìåð äèñêîâîäà |
FDD_Type db 0 |
; Êîîðäèíàòû ñåêòîðà |
FDD_Track DB ? |
FDD_Head DB ? |
FDD_Sector DB ? |
; Áëîê ðåçóëüòàòà îïåðàöèè |
FDC_ST0 DB ? |
FDC_ST1 DB ? |
FDC_ST2 DB ? |
FDC_C DB ? |
FDC_H DB ? |
FDC_R DB ? |
FDC_N DB ? |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
ReadRepCounter DB ? |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
RecalRepCounter DB ? |
endg |
; Îáëàñòü ïàìÿòè äëÿ õðàíåíèÿ ïðî÷èòàííîãî ñåêòîðà |
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?) |
fdd_motor_status db 0 |
timer_fdd_motor dd 0 |
;************************************* |
;* ÈÍÈÖÈÀËÈÇÀÖÈß ÐÅÆÈÌÀ ÏÄÏ ÄËß ÍÃÌÄ * |
;************************************* |
Init_FDC_DMA: |
pushad |
mov al,0 |
out 0x0c,al ; reset the flip-flop to a known state. |
mov al,6 ; mask channel 2 so we can reprogram it. |
out 0x0a,al |
mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy |
out 0x0b,al |
mov al,0 |
out 0x0c,al ; reset the flip-flop to a known state. |
mov eax,0xD000 |
out 0x04,al ; set the channel 2 starting address to 0 |
shr eax,8 |
out 0x04,al |
shr eax,8 |
out 0x81,al |
mov al,0 |
out 0x0c, al ; reset flip-flop |
mov al, 0xff ;set count (actual size -1) |
out 0x5, al |
mov al,0x1 ;[dmasize] ;(0x1ff = 511 / 0x23ff =9215) |
out 0x5,al |
mov al,2 |
out 0xa,al |
popad |
ret |
;*********************************** |
;* ÇÀÏÈÑÀÒÜ ÁÀÉÒ Â ÏÎÐÒ ÄÀÍÍÛÕ FDC * |
;* Ïàðàìåòðû: * |
;* AL - âûâîäèìûé áàéò. * |
;*********************************** |
FDCDataOutput: |
; pusha |
push eax ecx edx |
mov AH,AL ;çàïîìíèòü áàéò â AH |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
mov [FDC_Status],FDC_Normal |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïðèåìó äàííûõ |
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
mov ecx, 0x10000 ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
@@TestRS: |
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL,0C0h ;âûäåëèòü ðàçðÿäû 6 è 7 |
cmp AL,80h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
je @@OutByteToFDC |
loop @@TestRS |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
jmp @@End_5 |
; Âûâåñòè áàéò â ïîðò äàííûõ |
@@OutByteToFDC: |
inc DX |
mov AL,AH |
out DX,AL |
@@End_5: |
; popa |
pop edx ecx eax |
ret |
;****************************************** |
;* ÏÐÎ×ÈÒÀÒÜ ÁÀÉÒ ÈÇ ÏÎÐÒÀ ÄÀÍÍÛÕ FDC * |
;* Ïðîöåäóðà íå èìååò âõîäíûõ ïàðàìåòðîâ. * |
;* Âûõîäíûå äàííûå: * |
;* AL - ñ÷èòàííûé áàéò. * |
;****************************************** |
FDCDataInput: |
push ECX |
push DX |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
mov [FDC_Status],FDC_Normal |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïåðåäà÷å äàííûõ |
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
xor CX,CX ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
@@TestRS_1: |
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL,0C0h ;âûäëèòü ðàçðÿäû 6 è 7 |
cmp AL,0C0h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
je @@GetByteFromFDC |
loop @@TestRS_1 |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
jmp @@End_6 |
; Ââåñòè áàéò èç ïîðòà äàííûõ |
@@GetByteFromFDC: |
inc DX |
in AL,DX |
@@End_6: pop DX |
pop ECX |
ret |
;********************************************* |
;* ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;********************************************* |
FDCInterrupt: |
; Óñòàíîâèòü ôëàã ïðåðûâàíè |
mov [FDD_IntFlag],1 |
ret |
;****************************************** |
;* ÓÑÒÀÍÎÂÈÒÜ ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈÉ * |
;* ÍÃÌÄ * |
;****************************************** |
SetUserInterrupts: |
mov [fdc_irq_func],FDCInterrupt |
ret |
;******************************************* |
;* ÎÆÈÄÀÍÈÅ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;******************************************* |
WaitFDCInterrupt: |
pusha |
; Ñáðîñèòü áàéò ñîñòîÿíèÿ îïåðàöèè |
mov [FDC_Status],FDC_Normal |
; Ñáðîñèòü ôëàã ïðåðûâàíè |
mov [FDD_IntFlag],0 |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
mov eax,[timer_ticks] |
mov [TickCounter],eax |
; Îæèäàòü óñòàíîâêè ôëàãà ïðåðûâàíèÿ ÍÃÌÄ |
@@TestRS_2: |
cmp [FDD_IntFlag],0 |
jnz @@End_7 ;ïðåðûâàíèå ïðîèçîøëî |
call change_task |
mov eax,[timer_ticks] |
sub eax,[TickCounter] |
cmp eax,50 ;25 ;5 ;îæèäàòü 5 òèêîâ |
jb @@TestRS_2 |
; jl @@TestRS_2 |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
; mov [flp_status],0 |
@@End_7: popa |
ret |
;********************************* |
;* ÂÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ "A:" * |
;********************************* |
FDDMotorON: |
pusha |
; cmp [fdd_motor_status],1 |
; je fdd_motor_on |
mov al,[flp_number] |
cmp [fdd_motor_status],al |
je fdd_motor_on |
; Ïðîèçâåñòè ñáðîñ êîíòðîëëåðà ÍÃÌÄ |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,0 |
out DX,AL |
; Âûáðàòü è âêëþ÷èòü ìîòîð äèñêîâîäà |
cmp [flp_number],1 |
jne FDDMotorON_B |
; call FDDMotorOFF_B |
mov AL,1Ch ; Floppy A |
jmp FDDMotorON_1 |
FDDMotorON_B: |
; call FDDMotorOFF_A |
mov AL,2Dh ; Floppy B |
FDDMotorON_1: |
out DX,AL |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
mov eax,[timer_ticks] |
mov [TickCounter],eax |
; Îæèäàòü 0,5 ñ |
@@dT: |
call change_task |
mov eax,[timer_ticks] |
sub eax,[TickCounter] |
cmp eax,50 ;10 |
jb @@dT |
cmp [flp_number],1 |
jne fdd_motor_on_B |
mov [fdd_motor_status],1 |
jmp fdd_motor_on |
fdd_motor_on_B: |
mov [fdd_motor_status],2 |
fdd_motor_on: |
call save_timer_fdd_motor |
popa |
ret |
;***************************************** |
;* ÑÎÕÐÀÍÅÍÈÅ ÓÊÀÇÀÒÅËß ÂÐÅÌÅÍÈ * |
;***************************************** |
save_timer_fdd_motor: |
mov eax,[timer_ticks] |
mov [timer_fdd_motor],eax |
ret |
;***************************************** |
;* ÏÐÎÂÅÐÊÀ ÇÀÄÅÐÆÊÈ ÂÛÊËÞ×ÅÍÈß ÌÎÒÎÐÀ * |
;***************************************** |
align 4 |
check_fdd_motor_status: |
cmp [fdd_motor_status],0 |
je end_check_fdd_motor_status_1 |
mov eax,[timer_ticks] |
sub eax,[timer_fdd_motor] |
cmp eax,500 |
jb end_check_fdd_motor_status |
call FDDMotorOFF |
mov [fdd_motor_status],0 |
end_check_fdd_motor_status_1: |
mov [flp_status],0 |
end_check_fdd_motor_status: |
ret |
;********************************** |
;* ÂÛÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ * |
;********************************** |
FDDMotorOFF: |
push AX |
push DX |
cmp [flp_number],1 |
jne FDDMotorOFF_1 |
call FDDMotorOFF_A |
jmp FDDMotorOFF_2 |
FDDMotorOFF_1: |
call FDDMotorOFF_B |
FDDMotorOFF_2: |
pop DX |
pop AX |
; ñáðîñ ôëàãîâ êåøèðîâàíèÿ â ñâÿçè ñ óñòàðåâàíèåì èíôîðìàöèè |
mov [root_read],0 |
mov [flp_fat],0 |
ret |
FDDMotorOFF_A: |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,0Ch ; Floppy A |
out DX,AL |
ret |
FDDMotorOFF_B: |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,5h ; Floppy B |
out DX,AL |
ret |
;******************************* |
;* ÐÅÊÀËÈÁÐÎÂÊÀ ÄÈÑÊÎÂÎÄÀ "A:" * |
;******************************* |
RecalibrateFDD: |
pusha |
call save_timer_fdd_motor |
; Ïîäàòü êîìàíäó "Ðåêàëèáðîâêà" |
mov AL,07h |
call FDCDataOutput |
mov AL,00h |
call FDCDataOutput |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
call WaitFDCInterrupt |
; cmp [FDC_Status],0 |
; je no_fdc_status_error |
; mov [flp_status],0 |
;no_fdc_status_error: |
call save_timer_fdd_motor |
popa |
ret |
;***************************************************** |
;* ÏÎÈÑÊ ÄÎÐÎÆÊÈ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;***************************************************** |
SeekTrack: |
pusha |
call save_timer_fdd_motor |
; Ïîäàòü êîìàíäó "Ïîèñê" |
mov AL,0Fh |
call FDCDataOutput |
; Ïåðåäàòü áàéò íîìåðà ãîëîâêè/íàêîïèòåë |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
; Ïåðåäàòü áàéò íîìåðà äîðîæêè |
mov AL,[FDD_Track] |
call FDCDataOutput |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit |
; Ñîõðàíèòü ðåçóëüòàò ïîèñêà |
mov AL,08h |
call FDCDataOutput |
call FDCDataInput |
mov [FDC_ST0],AL |
call FDCDataInput |
mov [FDC_C],AL |
; Ïðîâåðèòü ðåçóëüòàò ïîèñêà |
; Ïîèñê çàâåðøåí? |
test [FDC_ST0],100000b |
je @@Err |
; Çàäàííûé òðåê íàéäåí? |
mov AL,[FDC_C] |
cmp AL,[FDD_Track] |
jne @@Err |
; Íîìåð ãîëîâêè ñîâïàäàåò ñ çàäàííûì? |
mov AL,[FDC_ST0] |
and AL,100b |
shr AL,2 |
cmp AL,[FDD_Head] |
jne @@Err |
; Îïåðàöèÿ çàâåðøåíà óñïåøíî |
mov [FDC_Status],FDC_Normal |
jmp @@Exit |
@@Err: ; Òðåê íå íàéäåí |
mov [FDC_Status],FDC_TrackNotFound |
; mov [flp_status],0 |
@@Exit: |
call save_timer_fdd_motor |
popa |
ret |
;******************************************************* |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;******************************************************* |
ReadSector: |
pushad |
call save_timer_fdd_motor |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
mov AX,0 |
mov DX,03F7h |
out DX,AL |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
mov [dmamode],0x46 |
call Init_FDC_DMA |
; Ïîäàòü êîìàíäó "×òåíèå äàííûõ" |
mov AL,0E6h ;÷òåíèå â ìóëüòèòðåêîâîì ðåæèìå |
call FDCDataOutput |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
mov AL,[FDD_Track] |
call FDCDataOutput |
mov AL,[FDD_Head] |
call FDCDataOutput |
mov AL,[FDD_Sector] |
call FDCDataOutput |
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
call FDCDataOutput |
mov AL,18 ;+1; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
call FDCDataOutput |
mov AL,1Bh ;çíà÷åíèå GPL |
call FDCDataOutput |
mov AL,0FFh ;çíà÷åíèå DTL |
call FDCDataOutput |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit_1 |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
call GetStatusInfo |
test [FDC_ST0],11011000b |
jnz @@Err_1 |
mov [FDC_Status],FDC_Normal |
jmp @@Exit_1 |
@@Err_1: mov [FDC_Status],FDC_SectorNotFound |
; mov [flp_status],0 |
@@Exit_1: |
call save_timer_fdd_motor |
popad |
ret |
;******************************************************* |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;******************************************************* |
ReadSectWithRetr: |
pusha |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
mov [RecalRepCounter],0 |
@@TryAgain: |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
mov [ReadRepCounter],0 |
@@ReadSector_1: |
call ReadSector |
cmp [FDC_Status],0 |
je @@Exit_2 |
cmp [FDC_Status],1 |
je @@Err_3 |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè |
inc [ReadRepCounter] |
cmp [ReadRepCounter],3 |
jb @@ReadSector_1 |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
cmp [RecalRepCounter],3 |
jb @@TryAgain |
; mov [flp_status],0 |
@@Exit_2: |
popa |
ret |
@@Err_3: |
mov [flp_status],0 |
popa |
ret |
;******************************************************* |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;******************************************************* |
WriteSector: |
pushad |
call save_timer_fdd_motor |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
mov AX,0 |
mov DX,03F7h |
out DX,AL |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
mov [dmamode],0x4A |
call Init_FDC_DMA |
; Ïîäàòü êîìàíäó "Çàïèñü äàííûõ" |
mov AL,0xC5 ;0x45 ;çàïèñü â ìóëüòèòðåêîâîì ðåæèìå |
call FDCDataOutput |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
mov AL,[FDD_Track] |
call FDCDataOutput |
mov AL,[FDD_Head] |
call FDCDataOutput |
mov AL,[FDD_Sector] |
call FDCDataOutput |
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
call FDCDataOutput |
mov AL,18; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
call FDCDataOutput |
mov AL,1Bh ;çíà÷åíèå GPL |
call FDCDataOutput |
mov AL,0FFh ;çíà÷åíèå DTL |
call FDCDataOutput |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit_3 |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
call GetStatusInfo |
test [FDC_ST0],11000000b ;11011000b |
jnz @@Err_2 |
mov [FDC_Status],FDC_Normal |
jmp @@Exit_3 |
@@Err_2: mov [FDC_Status],FDC_SectorNotFound |
@@Exit_3: |
call save_timer_fdd_motor |
popad |
ret |
;******************************************************* |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;******************************************************* |
WriteSectWithRetr: |
pusha |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
mov [RecalRepCounter],0 |
@@TryAgain_1: |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
mov [ReadRepCounter],0 |
@@WriteSector_1: |
call WriteSector |
cmp [FDC_Status],0 |
je @@Exit_4 |
cmp [FDC_Status],1 |
je @@Err_4 |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè |
inc [ReadRepCounter] |
cmp [ReadRepCounter],3 |
jb @@WriteSector_1 |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
cmp [RecalRepCounter],3 |
jb @@TryAgain_1 |
@@Exit_4: |
popa |
ret |
@@Err_4: |
mov [flp_status],0 |
popa |
ret |
;********************************************* |
;* ÏÎËÓ×ÈÒÜ ÈÍÔÎÐÌÀÖÈÞ Î ÐÅÇÓËÜÒÀÒÅ ÎÏÅÐÀÖÈÈ * |
;********************************************* |
GetStatusInfo: |
push AX |
call FDCDataInput |
mov [FDC_ST0],AL |
call FDCDataInput |
mov [FDC_ST1],AL |
call FDCDataInput |
mov [FDC_ST2],AL |
call FDCDataInput |
mov [FDC_C],AL |
call FDCDataInput |
mov [FDC_H],AL |
call FDCDataInput |
mov [FDC_R],AL |
call FDCDataInput |
mov [FDC_N],AL |
pop AX |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/blkdev/fdc.inc |
---|
0,0 → 1,71 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
iglobal |
;function pointers. |
fdc_irq_func dd fdc_null |
endg |
uglobal |
dmasize db 0x0 |
dmamode db 0x0 |
endg |
fdc_init: ;start with clean tracks. |
mov edi,OS_BASE+0xD201 |
mov al,0 |
mov ecx,160 |
rep stosb |
ret |
fdc_irq: |
call [fdc_irq_func] |
fdc_null: |
ret |
save_image: |
call reserve_flp |
call restorefatchain |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_save_image |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],1 ; Ñåêòîð |
mov esi,RAMDISK |
call SeekTrack |
save_image_1: |
push esi |
call take_data_from_application_1 |
pop esi |
add esi,512 |
call WriteSectWithRetr |
; call WriteSector |
cmp [FDC_Status],0 |
jne unnecessary_save_image |
inc [FDD_Sector] |
cmp [FDD_Sector],19 |
jne save_image_1 |
mov [FDD_Sector],1 |
inc [FDD_Head] |
cmp [FDD_Head],2 |
jne save_image_1 |
mov [FDD_Head],0 |
inc [FDD_Track] |
call SeekTrack |
cmp [FDD_Track],80 |
jne save_image_1 |
unnecessary_save_image: |
mov [fdc_irq_func],fdc_null |
popa |
mov [flp_status],0 |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/blkdev/ide_cache.inc |
---|
0,0 → 1,922 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;************************************************************************** |
; |
; [cache_ide[X]_pointer] |
; or [cache_ide[X]_data_pointer] first entry in cache list |
; |
; +0 - lba sector |
; +4 - state of cache sector |
; 0 = empty |
; 1 = used for read ( same as in hd ) |
; 2 = used for write ( differs from hd ) |
; |
; [cache_ide[X]_system_data] |
; or [cache_ide[x]_appl_data] - cache entries |
; |
;************************************************************************** |
$Revision$ |
align 4 |
write_cache: |
;----------------------------------------------------------- |
; write all changed sectors to disk |
;----------------------------------------------------------- |
push eax ecx edx esi edi |
; write difference ( 2 ) from cache to hd |
call calculate_cache |
add esi,8 |
mov edi,1 |
write_cache_more: |
cmp dword [esi+4],2 ; if cache slot is not different |
jne .write_chain |
mov dword [esi+4],1 ; same as in hd |
mov eax,[esi] ; eax = sector to write |
cmp eax,[PARTITION_START] |
jb danger |
cmp eax,[PARTITION_END] |
ja danger |
cmp [hdpos], 0x80 |
jae @f |
; DMA write is permitted only if [allow_dma_access]=1 |
cmp [allow_dma_access], 2 |
jae .nodma |
cmp [dma_hdd], 1 |
jnz .nodma |
@@: |
; ¡ê¥¤¨ï¥¬ § ¯¨áì 楯®çª¨ ¯®á«¥¤®¢ ⥫ìëå ᥪâ®à®¢ ¢ ®¤® ®¡à 饨¥ ª ¤¨áªã |
cmp ecx, 1 |
jz .nonext |
cmp dword [esi+8+4], 2 |
jnz .nonext |
push eax |
inc eax |
cmp eax, [esi+8] |
pop eax |
jnz .nonext |
cmp [cache_chain_started], 1 |
jz @f |
mov [cache_chain_started], 1 |
mov [cache_chain_size], 0 |
mov [cache_chain_pos], edi |
mov [cache_chain_ptr], esi |
@@: |
inc [cache_chain_size] |
cmp [cache_chain_size], 16 |
jnz .continue |
jmp .write_chain |
.nonext: |
call flush_cache_chain |
mov [cache_chain_size], 1 |
mov [cache_chain_ptr], esi |
call write_cache_sector |
jmp .continue |
.nodma: |
call cache_write_pio |
.write_chain: |
call flush_cache_chain |
.continue: |
danger: |
add esi,8 |
inc edi |
dec ecx |
jnz write_cache_more |
call flush_cache_chain |
return_02: |
pop edi esi edx ecx eax |
ret |
flush_cache_chain: |
cmp [cache_chain_started], 0 |
jz @f |
call write_cache_chain |
mov [cache_chain_started], 0 |
@@: |
ret |
;-------------------------------------------------------------------- |
align 4 |
find_empty_slot: |
;----------------------------------------------------------- |
; find empty or read slot, flush cache if next 10% is used by write |
; output : edi = cache slot |
;----------------------------------------------------------- |
; push ecx esi |
search_again: |
call calculate_cache_3 |
shr ecx,3 |
search_for_empty: |
inc edi |
call calculate_cache_4 |
jbe inside_cache |
mov edi,1 |
inside_cache: |
push esi |
call calculate_cache_1 |
cmp dword [edi*8+esi+4],2 |
pop esi |
jb found_slot ; it's empty or read |
dec ecx |
jnz search_for_empty |
call write_cache ; no empty slots found, write all |
cmp [hd_error],0 |
jne found_slot_access_denied |
jmp search_again ; and start again |
found_slot: |
call calculate_cache_5 |
found_slot_access_denied: |
ret |
;-------------------------------------------------------------------- |
align 4 |
clear_hd_cache: |
mov [fat_in_cache],-1 |
mov [fat_change],0 |
ret |
;-------------------------------------------------------------------- |
align 4 |
calculate_cache: |
; mov ecx,cache_max ; entries in cache |
; mov esi,HD_CACHE+8 |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [hdpos],1 |
jne .ide1 |
cmp [hdd_appl_data],0 |
jne .ide0_appl_data |
mov ecx,[cache_ide0_system_sad_size] |
mov esi,[cache_ide0_pointer] |
ret |
.ide0_appl_data: |
mov ecx,[cache_ide0_appl_sad_size] |
mov esi,[cache_ide0_data_pointer] |
ret |
.ide1: |
cmp [hdpos],2 |
jne .ide2 |
cmp [hdd_appl_data],0 |
jne .ide1_appl_data |
mov ecx,[cache_ide1_system_sad_size] |
mov esi,[cache_ide1_pointer] |
ret |
.ide1_appl_data: |
mov ecx,[cache_ide1_appl_sad_size] |
mov esi,[cache_ide1_data_pointer] |
ret |
.ide2: |
cmp [hdpos],3 |
jne .ide3 |
cmp [hdd_appl_data],0 |
jne .ide2_appl_data |
mov ecx,[cache_ide2_system_sad_size] |
mov esi,[cache_ide2_pointer] |
ret |
.ide2_appl_data: |
mov ecx,[cache_ide2_appl_sad_size] |
mov esi,[cache_ide2_data_pointer] |
ret |
.ide3: |
cmp [hdpos],4 |
jne .noide |
cmp [hdd_appl_data],0 |
jne .ide3_appl_data |
mov ecx,[cache_ide3_system_sad_size] |
mov esi,[cache_ide3_pointer] |
ret |
.ide3_appl_data: |
mov ecx,[cache_ide3_appl_sad_size] |
mov esi,[cache_ide3_data_pointer] |
ret |
.noide: |
push eax |
mov eax,[hdpos] |
sub eax,80h |
cmp byte [BiosDisksData+eax*4+2], -1 |
jz @f |
movzx eax,byte [BiosDisksData+eax*4+2] |
imul eax,cache_ide1-cache_ide0 |
add eax,cache_ide0 |
jmp .get |
@@: |
imul eax,cache_ide1-cache_ide0 |
add eax,BiosDiskCaches |
.get: |
cmp [hdd_appl_data],0 |
jne .bd_appl_data |
mov ecx,[cache_ide0_system_sad_size-cache_ide0+eax] |
mov esi,[cache_ide0_pointer-cache_ide0+eax] |
pop eax |
ret |
.bd_appl_data: |
mov ecx,[cache_ide0_appl_sad_size-cache_ide0+eax] |
mov esi,[cache_ide0_data_pointer-cache_ide0+eax] |
pop eax |
ret |
;-------------------------------------------------------------------- |
align 4 |
calculate_cache_1: |
; lea esi,[edi*8+HD_CACHE] |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [hdpos],1 |
jne .ide1 |
cmp [hdd_appl_data],0 |
jne .ide0_appl_data |
mov esi,[cache_ide0_pointer] |
ret |
.ide0_appl_data: |
mov esi,[cache_ide0_data_pointer] |
ret |
.ide1: |
cmp [hdpos],2 |
jne .ide2 |
cmp [hdd_appl_data],0 |
jne .ide1_appl_data |
mov esi,[cache_ide1_pointer] |
ret |
.ide1_appl_data: |
mov esi,[cache_ide1_data_pointer] |
ret |
.ide2: |
cmp [hdpos],3 |
jne .ide3 |
cmp [hdd_appl_data],0 |
jne .ide2_appl_data |
mov esi,[cache_ide2_pointer] |
ret |
.ide2_appl_data: |
mov esi,[cache_ide2_data_pointer] |
ret |
.ide3: |
cmp [hdpos],4 |
jne .noide |
cmp [hdd_appl_data],0 |
jne .ide3_appl_data |
mov esi,[cache_ide3_pointer] |
ret |
.ide3_appl_data: |
mov esi,[cache_ide3_data_pointer] |
ret |
.noide: |
push eax |
mov eax,[hdpos] |
sub eax,80h |
cmp byte [BiosDisksData+eax*4+2], -1 |
jz @f |
movzx eax,byte [BiosDisksData+eax*4+2] |
imul eax,cache_ide1-cache_ide0 |
add eax,cache_ide0 |
jmp .get |
@@: |
imul eax,cache_ide1-cache_ide0 |
add eax,BiosDiskCaches |
.get: |
cmp [hdd_appl_data],0 |
jne .bd_appl_data |
mov esi,[cache_ide0_pointer-cache_ide0+eax] |
pop eax |
ret |
.bd_appl_data: |
mov esi,[cache_ide0_data_pointer-cache_ide0+eax] |
pop eax |
ret |
;-------------------------------------------------------------------- |
align 4 |
calculate_cache_2: |
; add esi,HD_CACHE+65536 |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [hdpos],1 |
jne .ide1 |
cmp [hdd_appl_data],0 |
jne .ide0_appl_data |
mov eax,[cache_ide0_system_data] |
ret |
.ide0_appl_data: |
mov eax,[cache_ide0_appl_data] |
ret |
.ide1: |
cmp [hdpos],2 |
jne .ide2 |
cmp [hdd_appl_data],0 |
jne .ide1_appl_data |
mov eax,[cache_ide1_system_data] |
ret |
.ide1_appl_data: |
mov eax,[cache_ide1_appl_data] |
ret |
.ide2: |
cmp [hdpos],3 |
jne .ide3 |
cmp [hdd_appl_data],0 |
jne .ide2_appl_data |
mov eax,[cache_ide2_system_data] |
ret |
.ide2_appl_data: |
mov eax,[cache_ide2_appl_data] |
ret |
.ide3: |
cmp [hdpos],4 |
jne .noide |
cmp [hdd_appl_data],0 |
jne .ide3_appl_data |
mov eax,[cache_ide3_system_data] |
ret |
.ide3_appl_data: |
mov eax,[cache_ide3_appl_data] |
ret |
.noide: |
mov eax,[hdpos] |
sub eax,80h |
cmp byte [BiosDisksData+eax*4+2], -1 |
jz @f |
movzx eax,byte [BiosDisksData+eax*4+2] |
imul eax,cache_ide1-cache_ide0 |
add eax,cache_ide0 |
jmp .get |
@@: |
imul eax,cache_ide1-cache_ide0 |
add eax,BiosDiskCaches |
.get: |
cmp [hdd_appl_data],0 |
jne .bd_appl_data |
mov eax,[cache_ide0_system_data-cache_ide0+eax] |
ret |
.bd_appl_data: |
mov eax,[cache_ide0_appl_data-cache_ide0+eax] |
ret |
;-------------------------------------------------------------------- |
align 4 |
calculate_cache_3: |
; mov ecx,cache_max*10/100 |
; mov edi,[cache_search_start] |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [hdpos],1 |
jne .ide1 |
cmp [hdd_appl_data],0 |
jne .ide0_appl_data |
mov ecx,[cache_ide0_system_sad_size] |
mov edi,[cache_ide0_search_start] |
ret |
.ide0_appl_data: |
mov ecx,[cache_ide0_appl_sad_size] |
mov edi,[cache_ide0_appl_search_start] |
ret |
.ide1: |
cmp [hdpos],2 |
jne .ide2 |
cmp [hdd_appl_data],0 |
jne .ide1_appl_data |
mov ecx,[cache_ide1_system_sad_size] |
mov edi,[cache_ide1_search_start] |
ret |
.ide1_appl_data: |
mov ecx,[cache_ide1_appl_sad_size] |
mov edi,[cache_ide1_appl_search_start] |
ret |
.ide2: |
cmp [hdpos],3 |
jne .ide3 |
cmp [hdd_appl_data],0 |
jne .ide2_appl_data |
mov ecx,[cache_ide2_system_sad_size] |
mov edi,[cache_ide2_search_start] |
ret |
.ide2_appl_data: |
mov ecx,[cache_ide2_appl_sad_size] |
mov edi,[cache_ide2_appl_search_start] |
ret |
.ide3: |
cmp [hdpos],4 |
jne .noide |
cmp [hdd_appl_data],0 |
jne .ide3_appl_data |
mov ecx,[cache_ide3_system_sad_size] |
mov edi,[cache_ide3_search_start] |
ret |
.ide3_appl_data: |
mov ecx,[cache_ide3_appl_sad_size] |
mov edi,[cache_ide3_appl_search_start] |
ret |
.noide: |
push eax |
mov eax,[hdpos] |
sub eax,80h |
cmp byte [BiosDisksData+eax*4+2], -1 |
jz @f |
movzx eax,byte [BiosDisksData+eax*4+2] |
imul eax,cache_ide1-cache_ide0 |
add eax,cache_ide0 |
jmp .get |
@@: |
imul eax,cache_ide1-cache_ide0 |
add eax,BiosDiskCaches |
.get: |
cmp [hdd_appl_data],0 |
jne .bd_appl_data |
mov ecx,[cache_ide0_system_sad_size-cache_ide0+eax] |
mov edi,[cache_ide0_search_start-cache_ide0+eax] |
pop eax |
ret |
.bd_appl_data: |
mov ecx,[cache_ide0_appl_sad_size-cache_ide0+eax] |
mov edi,[cache_ide0_appl_search_start-cache_ide0+eax] |
pop eax |
ret |
;-------------------------------------------------------------------- |
align 4 |
calculate_cache_4: |
; cmp edi,cache_max |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [hdpos],1 |
jne .ide1 |
cmp [hdd_appl_data],0 |
jne .ide0_appl_data |
cmp edi,[cache_ide0_system_sad_size] |
ret |
.ide0_appl_data: |
cmp edi,[cache_ide0_appl_sad_size] |
ret |
.ide1: |
cmp [hdpos],2 |
jne .ide2 |
cmp [hdd_appl_data],0 |
jne .ide1_appl_data |
cmp edi,[cache_ide1_system_sad_size] |
ret |
.ide1_appl_data: |
cmp edi,[cache_ide1_appl_sad_size] |
ret |
.ide2: |
cmp [hdpos],3 |
jne .ide3 |
cmp [hdd_appl_data],0 |
jne .ide2_appl_data |
cmp edi,[cache_ide2_system_sad_size] |
ret |
.ide2_appl_data: |
cmp edi,[cache_ide2_appl_sad_size] |
ret |
.ide3: |
cmp [hdpos],4 |
jne .noide |
cmp [hdd_appl_data],0 |
jne .ide3_appl_data |
cmp edi,[cache_ide3_system_sad_size] |
ret |
.ide3_appl_data: |
cmp edi,[cache_ide3_appl_sad_size] |
ret |
.noide: |
push eax |
mov eax,[hdpos] |
sub eax,80h |
cmp byte [BiosDisksData+eax*4+2], -1 |
jz @f |
movzx eax,byte [BiosDisksData+eax*4+2] |
imul eax,cache_ide1-cache_ide0 |
add eax,cache_ide0 |
jmp .get |
@@: |
imul eax,cache_ide1-cache_ide0 |
add eax,BiosDiskCaches |
.get: |
cmp [hdd_appl_data],0 |
jne .bd_appl_data |
cmp edi,[cache_ide0_system_sad_size-cache_ide0+eax] |
pop eax |
ret |
.bd_appl_data: |
cmp edi,[cache_ide0_appl_sad_size-cache_ide0+eax] |
pop eax |
ret |
;-------------------------------------------------------------------- |
align 4 |
calculate_cache_5: |
; mov [cache_search_start],edi |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [hdpos],1 |
jne .ide1 |
cmp [hdd_appl_data],0 |
jne .ide0_appl_data |
mov [cache_ide0_search_start],edi |
ret |
.ide0_appl_data: |
mov [cache_ide0_appl_search_start],edi |
ret |
.ide1: |
cmp [hdpos],2 |
jne .ide2 |
cmp [hdd_appl_data],0 |
jne .ide1_appl_data |
mov [cache_ide1_search_start],edi |
ret |
.ide1_appl_data: |
mov [cache_ide1_appl_search_start],edi |
ret |
.ide2: |
cmp [hdpos],3 |
jne .ide3 |
cmp [hdd_appl_data],0 |
jne .ide2_appl_data |
mov [cache_ide2_search_start],edi |
ret |
.ide2_appl_data: |
mov [cache_ide2_appl_search_start],edi |
ret |
.ide3: |
cmp [hdpos],4 |
jne .noide |
cmp [hdd_appl_data],0 |
jne .ide3_appl_data |
mov [cache_ide3_search_start],edi |
ret |
.ide3_appl_data: |
mov [cache_ide3_appl_search_start],edi |
ret |
.noide: |
push eax |
mov eax,[hdpos] |
sub eax,80h |
cmp byte [BiosDisksData+eax*4+2], -1 |
jz @f |
movzx eax,byte [BiosDisksData+eax*4+2] |
imul eax,cache_ide1-cache_ide0 |
add eax,cache_ide0 |
jmp .get |
@@: |
imul eax,cache_ide1-cache_ide0 |
add eax,BiosDiskCaches |
.get: |
cmp [hdd_appl_data],0 |
jne .bd_appl_data |
mov [cache_ide0_search_start-cache_ide0+eax],edi |
pop eax |
ret |
.bd_appl_data: |
mov [cache_ide0_appl_search_start-cache_ide0+eax],edi |
pop eax |
ret |
;-------------------------------------------------------------------- |
align 4 |
find_empty_slot_CD_cache: |
;----------------------------------------------------------- |
; find empty or read slot, flush cache if next 10% is used by write |
; output : edi = cache slot |
;----------------------------------------------------------- |
.search_again: |
call cd_calculate_cache_3 |
.search_for_empty: |
inc edi |
call cd_calculate_cache_4 |
jbe .inside_cache |
mov edi,1 |
.inside_cache: |
call cd_calculate_cache_5 |
ret |
;-------------------------------------------------------------------- |
clear_CD_cache: |
pusha |
.ide0: |
xor eax,eax |
cmp [cdpos],1 |
jne .ide1 |
mov [cache_ide0_search_start],eax |
mov ecx,[cache_ide0_system_sad_size] |
mov edi,[cache_ide0_pointer] |
call .clear |
mov [cache_ide0_appl_search_start],eax |
mov ecx,[cache_ide0_appl_sad_size] |
mov edi,[cache_ide0_data_pointer] |
jmp .continue |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
mov [cache_ide1_search_start],eax |
mov ecx,[cache_ide1_system_sad_size] |
mov edi,[cache_ide1_pointer] |
call .clear |
mov [cache_ide1_appl_search_start],eax |
mov ecx,[cache_ide1_appl_sad_size] |
mov edi,[cache_ide1_data_pointer] |
jmp .continue |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
mov [cache_ide2_search_start],eax |
mov ecx,[cache_ide2_system_sad_size] |
mov edi,[cache_ide2_pointer] |
call .clear |
mov [cache_ide2_appl_search_start],eax |
mov ecx,[cache_ide2_appl_sad_size] |
mov edi,[cache_ide2_data_pointer] |
jmp .continue |
.ide3: |
mov [cache_ide3_search_start],eax |
mov ecx,[cache_ide3_system_sad_size] |
mov edi,[cache_ide3_pointer] |
call .clear |
mov [cache_ide3_appl_search_start],eax |
mov ecx,[cache_ide3_appl_sad_size] |
mov edi,[cache_ide3_data_pointer] |
.continue: |
call .clear |
popa |
ret |
.clear: |
shl ecx,1 |
cld |
rep stosd |
ret |
;-------------------------------------------------------------------- |
align 4 |
cd_calculate_cache: |
; mov ecx,cache_max ; entries in cache |
; mov esi,HD_CACHE+8 |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [cdpos],1 |
jne .ide1 |
cmp [cd_appl_data],0 |
jne .ide0_appl_data |
mov ecx,[cache_ide0_system_sad_size] |
mov esi,[cache_ide0_pointer] |
ret |
.ide0_appl_data: |
mov ecx,[cache_ide0_appl_sad_size] |
mov esi,[cache_ide0_data_pointer] |
ret |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
cmp [cd_appl_data],0 |
jne .ide1_appl_data |
mov ecx,[cache_ide1_system_sad_size] |
mov esi,[cache_ide1_pointer] |
ret |
.ide1_appl_data: |
mov ecx,[cache_ide1_appl_sad_size] |
mov esi,[cache_ide1_data_pointer] |
ret |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
cmp [cd_appl_data],0 |
jne .ide2_appl_data |
mov ecx,[cache_ide2_system_sad_size] |
mov esi,[cache_ide2_pointer] |
ret |
.ide2_appl_data: |
mov ecx,[cache_ide2_appl_sad_size] |
mov esi,[cache_ide2_data_pointer] |
ret |
.ide3: |
cmp [cd_appl_data],0 |
jne .ide3_appl_data |
mov ecx,[cache_ide3_system_sad_size] |
mov esi,[cache_ide3_pointer] |
ret |
.ide3_appl_data: |
mov ecx,[cache_ide3_appl_sad_size] |
mov esi,[cache_ide3_data_pointer] |
ret |
;-------------------------------------------------------------------- |
align 4 |
cd_calculate_cache_1: |
; lea esi,[edi*8+HD_CACHE] |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [cdpos],1 |
jne .ide1 |
cmp [cd_appl_data],0 |
jne .ide0_appl_data |
mov esi,[cache_ide0_pointer] |
ret |
.ide0_appl_data: |
mov esi,[cache_ide0_data_pointer] |
ret |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
cmp [cd_appl_data],0 |
jne .ide1_appl_data |
mov esi,[cache_ide1_pointer] |
ret |
.ide1_appl_data: |
mov esi,[cache_ide1_data_pointer] |
ret |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
cmp [cd_appl_data],0 |
jne .ide2_appl_data |
mov esi,[cache_ide2_pointer] |
ret |
.ide2_appl_data: |
mov esi,[cache_ide2_data_pointer] |
ret |
.ide3: |
cmp [cd_appl_data],0 |
jne .ide3_appl_data |
mov esi,[cache_ide3_pointer] |
ret |
.ide3_appl_data: |
mov esi,[cache_ide3_data_pointer] |
ret |
;-------------------------------------------------------------------- |
align 4 |
cd_calculate_cache_2: |
; add esi,HD_CACHE+65536 |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [cdpos],1 |
jne .ide1 |
cmp [cd_appl_data],0 |
jne .ide0_appl_data |
mov eax,[cache_ide0_system_data] |
ret |
.ide0_appl_data: |
mov eax,[cache_ide0_appl_data] |
ret |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
cmp [cd_appl_data],0 |
jne .ide1_appl_data |
mov eax,[cache_ide1_system_data] |
ret |
.ide1_appl_data: |
mov eax,[cache_ide1_appl_data] |
ret |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
cmp [cd_appl_data],0 |
jne .ide2_appl_data |
mov eax,[cache_ide2_system_data] |
ret |
.ide2_appl_data: |
mov eax,[cache_ide2_appl_data] |
ret |
.ide3: |
cmp [cd_appl_data],0 |
jne .ide3_appl_data |
mov eax,[cache_ide3_system_data] |
ret |
.ide3_appl_data: |
mov eax,[cache_ide3_appl_data] |
ret |
;-------------------------------------------------------------------- |
align 4 |
cd_calculate_cache_3: |
; mov ecx,cache_max*10/100 |
; mov edi,[cache_search_start] |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [cdpos],1 |
jne .ide1 |
cmp [cd_appl_data],0 |
jne .ide0_appl_data |
mov edi,[cache_ide0_search_start] |
ret |
.ide0_appl_data: |
mov edi,[cache_ide0_appl_search_start] |
ret |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
cmp [cd_appl_data],0 |
jne .ide1_appl_data |
mov edi,[cache_ide1_search_start] |
ret |
.ide1_appl_data: |
mov edi,[cache_ide1_appl_search_start] |
ret |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
cmp [cd_appl_data],0 |
jne .ide2_appl_data |
mov edi,[cache_ide2_search_start] |
ret |
.ide2_appl_data: |
mov edi,[cache_ide2_appl_search_start] |
ret |
.ide3: |
cmp [cd_appl_data],0 |
jne .ide3_appl_data |
mov edi,[cache_ide3_search_start] |
ret |
.ide3_appl_data: |
mov edi,[cache_ide3_appl_search_start] |
ret |
;-------------------------------------------------------------------- |
align 4 |
cd_calculate_cache_4: |
; cmp edi,cache_max |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [cdpos],1 |
jne .ide1 |
cmp [cd_appl_data],0 |
jne .ide0_appl_data |
cmp edi,[cache_ide0_system_sad_size] |
ret |
.ide0_appl_data: |
cmp edi,[cache_ide0_appl_sad_size] |
ret |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
cmp [cd_appl_data],0 |
jne .ide1_appl_data |
cmp edi,[cache_ide1_system_sad_size] |
ret |
.ide1_appl_data: |
cmp edi,[cache_ide1_appl_sad_size] |
ret |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
cmp [cd_appl_data],0 |
jne .ide2_appl_data |
cmp edi,[cache_ide2_system_sad_size] |
ret |
.ide2_appl_data: |
cmp edi,[cache_ide2_appl_sad_size] |
ret |
.ide3: |
cmp [cd_appl_data],0 |
jne .ide3_appl_data |
cmp edi,[cache_ide3_system_sad_size] |
ret |
.ide3_appl_data: |
cmp edi,[cache_ide3_appl_sad_size] |
ret |
;-------------------------------------------------------------------- |
align 4 |
cd_calculate_cache_5: |
; mov [cache_search_start],edi |
; 1 - IDE0 ... 4 - IDE3 |
.ide0: |
cmp [cdpos],1 |
jne .ide1 |
cmp [cd_appl_data],0 |
jne .ide0_appl_data |
mov [cache_ide0_search_start],edi |
ret |
.ide0_appl_data: |
mov [cache_ide0_appl_search_start],edi |
ret |
.ide1: |
cmp [cdpos],2 |
jne .ide2 |
cmp [cd_appl_data],0 |
jne .ide1_appl_data |
mov [cache_ide1_search_start],edi |
ret |
.ide1_appl_data: |
mov [cache_ide1_appl_search_start],edi |
ret |
.ide2: |
cmp [cdpos],3 |
jne .ide3 |
cmp [cd_appl_data],0 |
jne .ide2_appl_data |
mov [cache_ide2_search_start],edi |
ret |
.ide2_appl_data: |
mov [cache_ide2_appl_search_start],edi |
ret |
.ide3: |
cmp [cd_appl_data],0 |
jne .ide3_appl_data |
mov [cache_ide3_search_start],edi |
ret |
.ide3_appl_data: |
mov [cache_ide3_appl_search_start],edi |
ret |
;-------------------------------------------------------------------- |
;align 4 |
;calculate_linear_to_real: |
; shr eax, 12 |
; mov eax, [page_tabs+eax*4] |
; and eax, 0xFFFFF000 |
; ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/blkdev/cdrom.inc |
---|
0,0 → 1,271 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
$Revision$ |
sys_cd_audio: |
cmp word [cdbase],word 0 |
jnz @f |
mov eax,1 |
ret |
@@: |
; eax=1 cdplay at ebx 0x00FFSSMM |
; eax=2 get tracklist size of ecx to [ebx] |
; eax=3 stop/pause playing |
cmp eax,1 |
jnz nocdp |
call sys_cdplay |
ret |
nocdp: |
cmp eax,2 |
jnz nocdtl |
mov edi,[TASK_BASE] |
add edi,TASKDATA.mem_start |
add ebx,[edi] |
call sys_cdtracklist |
ret |
nocdtl: |
cmp eax,3 |
jnz nocdpause |
call sys_cdpause |
ret |
nocdpause: |
mov eax,0xffffff01 |
ret |
sys_cd_atapi_command: |
pushad |
mov dx,word [cdbase] |
add dx,6 |
mov ax,word [cdid] |
out dx,al |
mov esi,10 |
call delay_ms |
mov dx,word [cdbase] |
add dx,7 |
in al,dx |
and al,0x80 |
cmp al,0 |
jnz res |
jmp cdl6 |
res: |
mov dx,word [cdbase] |
add dx,7 |
mov al,0x8 |
out dx,al |
mov dx,word [cdbase] |
add dx,0x206 |
mov al,0xe |
out dx,al |
mov esi,1 |
call delay_ms |
mov dx,word [cdbase] |
add dx,0x206 |
mov al,0x8 |
out dx,al |
mov esi,30 |
call delay_ms |
xor cx,cx |
cdl5: |
inc cx |
cmp cx,10 |
jz cdl6 |
mov dx,word [cdbase] |
add dx,7 |
in al,dx |
and al,0x88 |
cmp al,0x00 |
jz cdl5 |
mov esi,100 |
call delay_ms |
jmp cdl5 |
cdl6: |
mov dx,word [cdbase] |
add dx,4 |
mov al,0 |
out dx,al |
mov dx,word [cdbase] |
add dx,5 |
mov al,0 |
out dx,al |
mov dx,word [cdbase] |
add dx,7 |
mov al,0xec |
out dx,al |
mov esi,5 |
call delay_ms |
mov dx,word [cdbase] |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,128 |
out dx,al |
add dx,2 |
mov al,0xa0 |
out dx,al |
xor cx,cx |
mov dx,word [cdbase] |
add dx,7 |
cdl1: |
inc cx |
cmp cx,100 |
jz cdl2 |
in al,dx |
and ax,0x88 |
cmp al,0x8 |
jz cdl2 |
mov esi,2 |
call delay_ms |
jmp cdl1 |
cdl2: |
popad |
ret |
sys_cdplay: |
mov ax,5 |
push ax |
push ebx |
cdplay: |
call sys_cd_atapi_command |
cli |
mov dx,word [cdbase] |
mov ax,0x0047 |
out dx,ax |
mov al,1 |
mov ah,[esp+0] ; min xx |
out dx,ax |
mov ax,[esp+1] ; fr sec |
out dx,ax |
mov ax,256+99 |
out dx,ax |
mov ax,0x0001 |
out dx,ax |
mov ax,0x0000 |
out dx,ax |
mov esi,10 |
call delay_ms |
sti |
add dx,7 |
in al,dx |
test al,1 |
jz cdplayok |
mov ax,[esp+4] |
dec ax |
mov [esp+4],ax |
cmp ax,0 |
jz cdplayfail |
jmp cdplay |
cdplayfail: |
cdplayok: |
pop ebx |
pop ax |
xor eax, eax |
ret |
sys_cdtracklist: |
push ebx |
tcdplay: |
call sys_cd_atapi_command |
mov dx,word [cdbase] |
mov ax,0x43+2*256 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,200 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
in al,dx |
mov cx,1000 |
mov dx,word [cdbase] |
add dx,7 |
cld |
cdtrnwewait: |
mov esi,10 |
call delay_ms |
in al,dx |
and al,128 |
cmp al,0 |
jz cdtrl1 |
loop cdtrnwewait |
cdtrl1: |
; read the result |
mov ecx,[esp+0] |
mov dx,word [cdbase] |
cdtrread: |
add dx,7 |
in al,dx |
and al,8 |
cmp al,8 |
jnz cdtrdone |
sub dx,7 |
in ax,dx |
mov [ecx],ax |
add ecx,2 |
jmp cdtrread |
cdtrdone: |
pop ecx |
xor eax, eax |
ret |
sys_cdpause: |
call sys_cd_atapi_command |
mov dx,word [cdbase] |
mov ax,0x004B |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov esi,10 |
call delay_ms |
add dx,7 |
in al,dx |
xor eax, eax |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/blkdev/. |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
+*.obj |