Subversion Repositories Kolibri OS

Rev

Rev 2644 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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