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 |