Subversion Repositories Kolibri OS

Rev

Rev 2 | Go to most recent revision | Details | 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