Subversion Repositories Kolibri OS

Rev

Rev 2644 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2644 clevermous 1
; Callbacks which implement tmpdisk-specific disk functions for tmpdisk.asm.
2
 
3
; The first argument of every callback is .userdata = userdata arg of AddDisk.
4
; For tmpdisk, .userdata is the disk id, one of 0,...,max_num_disks-1.
5
 
6
DISK_STATUS_OK              = 0 ; success
7
DISK_STATUS_GENERAL_ERROR   = -1; if no other code is suitable
8
DISK_STATUS_INVALID_CALL    = 1 ; invalid input parameters
9
DISK_STATUS_NO_MEDIA        = 2 ; no media present
10
DISK_STATUS_END_OF_MEDIA    = 3 ; end of media while reading/writing data
11
 
12
; The last function that is called for the given disk. The kernel calls it when
13
; the kernel has finished all operations with the disk and it is safe to free
14
; all driver-specific data identified by 'userdata'.
15
proc tmpdisk_close
16
  virtual at esp+4
17
    .userdata dd ?
18
  end virtual
19
; Free the memory for disk and zero global variables.
20
        mov     edx, [.userdata]
21
        mov     [disk_sizes+edx*4], 0
22
        xor     eax, eax
23
        xchg    eax, [disk_pointers+edx*4]
5044 clevermous 24
        invoke  KernelFree, eax
2644 clevermous 25
        retn    4
26
endp
27
 
28
struc DISKMEDIAINFO
29
{
30
  .flags      dd ?
31
DISK_MEDIA_READONLY = 1
32
  .sectorsize dd ?
33
  .capacity   dq ?
34
}
35
virtual at 0
36
DISKMEDIAINFO DISKMEDIAINFO
37
end virtual
38
 
39
; Returns information about disk media.
40
proc tmpdisk_querymedia
41
  virtual at esp+4
42
    .userdata dd ?
43
    .info dd ?
44
  end virtual
45
; Media is always present, sector size is always 512 bytes,
46
; the size of disk in sectors is stored in a global variable.
47
        mov     edx, [.userdata]
48
        mov     ecx, [.info]
49
        mov     [ecx+DISKMEDIAINFO.flags], 0
50
        mov     [ecx+DISKMEDIAINFO.sectorsize], 512
51
        mov     eax, [disk_sizes+edx*4]
52
        mov     dword [ecx+DISKMEDIAINFO.capacity], eax
53
        mov     dword [ecx+DISKMEDIAINFO.capacity+4], 0
54
; Return zero as an indicator of success.
55
        xor     eax, eax
56
        retn    8
57
endp
58
 
59
; Reads one or more sectors from the device.
60
tmpdisk_read:
61
        xor     edx, edx ; 0 = reading
62
        jmp     tmpdisk_readwrite
63
 
64
; Writes one or more sectors to the device.
65
tmpdisk_write:
66
        mov     dl, 1 ; 1 = writing
67
; Fall through to tmpdisk_readwrite.
68
 
69
; Common procedure for reading and writing.
70
; dl = 0 for reading, dl = 1 for writing.
71
; Arguments of tmpdisk_read and tmpdisk_write are the same,
72
; they continue to be stack arguments of this procedure.
73
proc tmpdisk_readwrite \
74
  userdata:dword, \
75
  buffer:dword, \
76
  start_sector:qword, \
77
  numsectors_ptr:dword
78
; 1. Save used registers to be stdcall.
79
        push    esi edi
80
        mov     esi, [userdata]
81
        mov     edi, [numsectors_ptr]
82
; 1. Determine number of sectors to be transferred.
83
; This is either the requested number of sectors or number of sectors
84
; up to the disk boundary, depending of what is less.
85
        xor     ecx, ecx
86
; 1a. Test whether [start_sector] is less than [disk_sizes] for selected disk.
87
; If so, calculate number of sectors between [start_sector] and [disk_sizes].
88
; Otherwise, the actual number of sectors is zero.
89
        cmp     dword [start_sector+4], ecx
90
        jnz     .got_number
91
        mov     eax, [disk_sizes+esi*4]
92
        sub     eax, dword [start_sector]
93
        jbe     .got_number
94
; 1b. Get the requested number of sectors.
95
        mov     ecx, [edi]
96
; 1c. If it is greater than number of sectors calculated in 1a, use the value
97
; from 1a.
98
        cmp     ecx, eax
99
        jb      .got_number
100
        mov     ecx, eax
101
.got_number:
102
; 2. Compare the actual number of sectors with requested. If they are
103
; equal, set eax (it will be the returned value) to zero. Otherwise,
104
; use DISK_STATUS_END_OF_MEDIA.
105
        xor     eax, eax
106
        cmp     ecx, [edi]
107
        jz      @f
108
        mov     al, DISK_STATUS_END_OF_MEDIA
109
@@:
110
; 3. Store the actual number of sectors.
111
        mov     [edi], ecx
112
; 4. Calculate source and destination addresses.
113
        mov     edi, dword [start_sector]
114
        shl     edi, 9
115
        add     edi, [disk_pointers+esi*4]
116
        mov     esi, [buffer]
117
; 5. Calculate number of dwords to be transferred.
118
        shl     ecx, 9-2
119
; 6. Now esi = [buffer], edi = pointer inside disk.
120
; This is normal for write operations;
121
; exchange esi and edi for read operations.
122
        test    dl, dl
123
        jnz     @f
124
        xchg    esi, edi
125
@@:
126
; 7. Copy data.
127
        rep movsd
128
; 8. Restore used registers to be stdcall and return.
129
; The value in eax was calculated in step 2.
130
        pop     edi esi
131
        ret
132
endp
133
 
134
; The kernel calls this function when initializing cache subsystem for
135
; the media. This call allows the driver to adjust the cache size.
136
proc tmpdisk_adjust_cache_size
137
  virtual at esp+4
138
    .userdata dd ?
139
    .suggested_size dd ?
140
  end virtual
141
; Since tmpdisk does not need cache, just return 0.
142
        xor     eax, eax
143
        retn    8
144
endp