Rev 1 | Rev 19 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | ha | 1 | ;### fdc.inc ### Menuetos floppy stuff. |
2 | ;Version 0.2: Write individual tracks. / Sync ramdisk <-> floppy |
||
3 | ;Version 0.1: Write full ramdisk to floppy. |
||
4 | ;£loppyright Tolle. |
||
5 | |||
6 | ;depends on: |
||
7 | ;restorefatchain |
||
8 | ;memmove |
||
9 | ;Int 6 (sys32.inc) should call fdc_irq func. |
||
10 | ;The ramdisk should be at 0x100000 |
||
11 | |||
12 | ;Keeping track of the tracks. |
||
13 | iglobal |
||
14 | cylinder db 0 |
||
15 | sector db 1 |
||
16 | head db 0 |
||
17 | |||
18 | ;Memory and dma variables. |
||
19 | fdcmem dd 0x100000 |
||
20 | cpymem dd 0x100000 |
||
21 | dmamem dd 0x100000 |
||
22 | endg |
||
23 | |||
24 | uglobal |
||
25 | dmasize db 0x0 |
||
26 | dmamode db 0x0 |
||
27 | endg |
||
28 | |||
29 | iglobal |
||
30 | ;function pointers. |
||
31 | fdc_irq_func dd fdc_null |
||
32 | fdc_pump_func dd fdc_null |
||
33 | endg |
||
34 | |||
35 | uglobal |
||
36 | ;General stuff |
||
37 | fdc_st0 db 0 ;status register 0 of last resultphase. |
||
38 | fdc_mutex db 0 ;wait in line. (Block calling app) |
||
39 | fdc_callspending db 0 ;mystery sauce |
||
40 | fdc_settings dd 0 ;bitfield. |
||
41 | endg |
||
42 | ;Bit 0 enable direct file write [yes/no] |
||
43 | |||
44 | fdc_set: ;ebx: fdc_settings bitfield. |
||
45 | mov [fdc_settings],ebx |
||
46 | ret |
||
47 | |||
48 | fdc_get: ;returns fdc_settings in ecx |
||
49 | mov ecx, [fdc_settings] |
||
50 | ret |
||
51 | |||
52 | fdc_init: ;start with clean tracks. |
||
53 | mov edi,0xD201 |
||
54 | mov al,0 |
||
55 | mov ecx,160 |
||
56 | rep stosb |
||
57 | ret |
||
58 | |||
59 | fdc_filesave: ;ebx: cluster to be saved. |
||
60 | pusha ;returns immediately. does not trigger a write. |
||
61 | mov eax,ebx |
||
62 | add eax,31 |
||
63 | mov bl,18 |
||
64 | div bl |
||
65 | mov ah,0 |
||
66 | add eax,0xD201 |
||
67 | mov [eax],byte 1 ;This track is now dirty. |
||
68 | popa |
||
69 | ret |
||
70 | |||
71 | |||
72 | fdc_writeramdisk: ;mark all tracks as dirty. |
||
73 | mov edi,0xD201 |
||
74 | mov al,1 |
||
75 | mov ecx,160 |
||
76 | rep stosb |
||
77 | jmp fdc_commitflush |
||
78 | fdc_commitfile: ;flush dirty tracks to floppy |
||
79 | test [fdc_settings],1 ;...but only if this is really wanted by the user. |
||
80 | je fdc_commitend |
||
81 | fdc_commitflush: |
||
82 | cmp [fdc_callspending],5 |
||
83 | je fdc_commitend |
||
84 | inc [fdc_callspending] |
||
85 | cmp [fdc_callspending],1 |
||
86 | je fdc_commitonce |
||
87 | fdc_commitend: |
||
88 | ret |
||
89 | |||
90 | fdc_commitonce: ;One at a time. |
||
91 | .stall: |
||
92 | cli |
||
93 | cmp [fdc_mutex],0 |
||
94 | jne .stallret |
||
95 | mov [fdc_mutex],1 |
||
96 | jmp .goahead |
||
97 | .stallret: |
||
98 | sti |
||
99 | jmp .stall |
||
100 | .goahead: |
||
101 | sti |
||
102 | |||
103 | fdc_commitramdisk: |
||
104 | |||
105 | call restorefatchain |
||
106 | ;Move the bootsector to a safe place. |
||
107 | mov eax,0x100000 |
||
108 | mov ebx,0xD000 |
||
109 | mov ecx,512 |
||
110 | call memmove |
||
111 | ;Always write the FAT table |
||
112 | mov eax,0xD201 |
||
113 | mov [eax],byte 1 |
||
114 | inc eax |
||
115 | mov [eax],byte 1 |
||
116 | |||
117 | mov [dmamode],0x4A ;read from memory to floppy. |
||
118 | mov [dmasize],0x1 ;read 512 bytes sectors. |
||
119 | mov [fdc_irq_func],fdc_commitramdisk1 |
||
120 | call fdc_floppy_on ;start floppy A: moter starts interruptflow. |
||
121 | ret |
||
122 | fdc_commitramdisk1: |
||
123 | mov [fdc_irq_func],fdc_recalibrate_result |
||
124 | mov [fdc_pump_func],fdc_commitramdisk2 |
||
125 | call fdc_recalibrate ;retract the head to cylinder 0, sector 1 |
||
126 | ret |
||
127 | fdc_commitramdisk2: |
||
128 | mov[head],0 ;set variables. |
||
129 | mov[cylinder],0 |
||
130 | mov [sector],1 |
||
131 | mov[cpymem],0x102400 |
||
132 | mov [fdc_pump_func],fdc_fullpump |
||
133 | call fdc_write ;fdc_write will continue interruptflow |
||
134 | ret |
||
135 | |||
136 | fdc_fullpump: |
||
137 | add [dmamem],512 |
||
138 | add [sector],1 |
||
139 | cmp [sector],19 |
||
140 | jne .clusterwrite |
||
141 | sub [dmamem],9216 |
||
142 | mov eax,[cpymem] |
||
143 | mov ebx,[fdcmem] |
||
144 | mov ecx,9216 |
||
145 | call memmove |
||
146 | add [cpymem],9216 |
||
147 | cmp [head],0 |
||
148 | je .nocylinderchange |
||
149 | add [cylinder],1 |
||
150 | .nocylinderchange: |
||
151 | xor [head],1 |
||
152 | cmp [cylinder],80 |
||
153 | jne .noendofwrite |
||
154 | mov[fdc_irq_func],fdc_complete |
||
155 | call fdc_floppy_off |
||
156 | call fdc_init |
||
157 | jmp .end |
||
158 | .noendofwrite: |
||
159 | mov [sector],1 |
||
160 | .clusterwrite: |
||
161 | xor eax,eax |
||
162 | mov al,[cylinder] |
||
163 | shl eax,1 |
||
164 | add al,[head] |
||
165 | add eax,0xD201 |
||
166 | mov bl,[eax] |
||
167 | cmp bl,1 |
||
168 | jne fdc_fullpump |
||
169 | call fdc_write |
||
170 | .end: |
||
171 | ret |
||
172 | |||
173 | fdc_write: |
||
174 | call fdc_program_dma |
||
175 | call fdc_seek |
||
176 | ret |
||
177 | |||
178 | fdc_seek: |
||
179 | mov al, 0x0f |
||
180 | call fdc_write_reg |
||
181 | mov al,[head] |
||
182 | shl al,2 |
||
183 | call fdc_write_reg |
||
184 | mov al,[cylinder] |
||
185 | call fdc_write_reg |
||
186 | mov [fdc_irq_func],fdc_seek_result |
||
187 | ret |
||
188 | |||
189 | fdc_seek_result: |
||
190 | call fdc_sensei |
||
191 | cmp al,[cylinder] |
||
192 | je .succes |
||
193 | call fdc_seek |
||
194 | jmp .end |
||
195 | .succes: |
||
196 | call fdc_write_sector |
||
197 | .end: |
||
198 | ret |
||
199 | |||
200 | fdc_write_sector: |
||
201 | mov al,0x45 ;write sector command |
||
202 | fdc_commandphase: |
||
203 | call fdc_write_reg |
||
204 | mov al,[head] |
||
205 | shl al,2 |
||
206 | call fdc_write_reg |
||
207 | mov al,[cylinder] |
||
208 | call fdc_write_reg |
||
209 | mov al,[head] |
||
210 | call fdc_write_reg |
||
211 | mov al,[sector] |
||
212 | call fdc_write_reg |
||
213 | mov al,2 ;Sector size (2 ~> 512 bytes) |
||
214 | call fdc_write_reg |
||
215 | mov al,18 ;last sector on track. |
||
216 | call fdc_write_reg |
||
217 | mov al,27 ;length of GAP3 |
||
218 | call fdc_write_reg |
||
219 | mov al,0xFF ;data length, ignored. |
||
220 | call fdc_write_reg |
||
221 | mov [fdc_irq_func],fdc_resultphase |
||
222 | ret |
||
223 | |||
224 | fdc_resultphase: |
||
225 | call fdc_read_reg |
||
226 | mov [fdc_st0],al |
||
227 | mov cx,6 |
||
228 | .readresult: |
||
229 | call fdc_read_reg |
||
230 | loop .readresult |
||
231 | and [fdc_st0],11000000b |
||
232 | cmp [fdc_st0],byte 0 |
||
233 | jz .succes |
||
234 | call fdc_seek |
||
235 | jmp .end |
||
236 | .succes: |
||
237 | call [fdc_pump_func] |
||
238 | .end: |
||
239 | ret |
||
240 | |||
241 | fdc_sensei: |
||
242 | mov al,0x08 ;get interrupt status command |
||
243 | call fdc_write_reg |
||
244 | call fdc_read_reg ;get result in al; |
||
245 | and al,0x80 |
||
246 | cmp al,0x80 |
||
247 | je fdc_sensei ;retry |
||
248 | call fdc_read_reg |
||
249 | ret |
||
250 | |||
251 | fdc_program_dma: |
||
252 | mov al,0 |
||
253 | out 0x0c,al ; reset the flip-flop to a known state. |
||
254 | mov al,6 ; mask channel 2 so we can reprogram it. |
||
255 | out 0x0a,al |
||
256 | mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy |
||
257 | out 0x0b,al |
||
258 | mov al,0 |
||
259 | out 0x0c,al ; reset the flip-flop to a known state. |
||
260 | mov eax,[dmamem] |
||
261 | out 0x04,al ; set the channel 2 starting address to 0 |
||
262 | shr eax,8 |
||
263 | out 0x04,al |
||
264 | shr eax,8 |
||
265 | out 0x81,al |
||
266 | mov al,0 |
||
267 | out 0x0c, al ; reset flip-flop |
||
268 | mov al, 0xff ;set count (actual size -1) |
||
269 | out 0x5, al |
||
270 | mov al, [dmasize] ;(0x1ff = 511 / 0x23ff =9215) |
||
271 | out 0x5,al |
||
272 | mov al,2 |
||
273 | out 0xa,al |
||
274 | ret |
||
275 | |||
276 | fdc_recalibrate: |
||
277 | mov al,0x07 ;calibrate command |
||
278 | call fdc_write_reg |
||
279 | mov al,0 ;select drive 0 |
||
280 | call fdc_write_reg |
||
281 | ret |
||
282 | |||
283 | fdc_recalibrate_result: |
||
284 | mov al,0x08 ;get interrupt status command |
||
285 | call fdc_write_reg ;send it |
||
286 | call fdc_read_reg ;get command in al; |
||
287 | cmp al,0x80 |
||
288 | je fdc_recalibrate_result |
||
289 | mov ah,al |
||
290 | call fdc_read_reg |
||
291 | cmp ah,0x70 |
||
292 | jne .end |
||
293 | call fdc_recalibrate |
||
294 | jmp .reallyend |
||
295 | .end: |
||
296 | call [fdc_pump_func] |
||
297 | .reallyend: |
||
298 | ret |
||
299 | |||
300 | fdc_busy: |
||
301 | .command_check: |
||
302 | mov dx,0x3F4 |
||
303 | in al,dx |
||
304 | and al,0x10 |
||
305 | cmp al,0x10 |
||
306 | je .command_check |
||
307 | ret |
||
308 | |||
309 | fdc_read_reg: |
||
310 | status_check: |
||
311 | mov dx,0x3F4 |
||
312 | in al,dx |
||
313 | and al,0xc0 |
||
314 | cmp al,0xc0 |
||
315 | jne status_check |
||
316 | mov dx, 0x3F5 |
||
317 | in al, dx |
||
318 | ret |
||
319 | |||
320 | fdc_write_reg: |
||
321 | mov bl,al |
||
322 | .command_check: |
||
323 | mov dx,0x3F4 |
||
324 | in al,dx |
||
325 | and al,0x80 |
||
326 | cmp al,0x80 |
||
327 | jne .command_check |
||
328 | mov al,bl |
||
329 | mov dx,0x3F5 |
||
330 | out dx,al |
||
331 | ret |
||
332 | |||
333 | fdc_floppy_off: |
||
334 | mov al,0xC |
||
335 | mov dx,0x3f2 |
||
336 | out dx,al |
||
337 | ret |
||
338 | |||
339 | fdc_floppy_on: |
||
340 | mov dx,0x3f2 |
||
341 | mov al,0x0 |
||
342 | out dx,al |
||
343 | mov al,0x1C |
||
344 | out dx,al |
||
345 | |||
346 | mov eax,50 |
||
347 | call delay_hs |
||
348 | ret |
||
349 | |||
350 | fdc_complete: |
||
351 | mov eax,0xD000 |
||
352 | mov ebx,0x100000 |
||
353 | mov ecx,512 |
||
354 | call memmove |
||
355 | |||
356 | mov [fdc_irq_func],fdc_null |
||
357 | mov [fdc_mutex],0 |
||
358 | dec [fdc_callspending] |
||
359 | cmp [fdc_callspending],0 |
||
360 | je .realyend |
||
361 | mov [fdc_mutex],1 |
||
362 | call fdc_commitramdisk |
||
363 | .realyend: |
||
364 | ret |
||
365 | |||
366 | fdc_irq: |
||
367 | call [fdc_irq_func] |
||
368 | fdc_null: |
||
369 | ret-> |