Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 1634 → Rev 1635

/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