]>
wirehaze git hosting - BOS.git/blob - kernel/fdc/fdc.asm
1 ;----------------------------------------------------------;
2 ; BOS kernel Christoffer Bubach, 2004-2012. ;
3 ;----------------------------------------------------------;
5 ; floppy disk driver. ;
7 ;----------------------------------------------------------;
10 ;---------------------------;
11 ; variables and contants ;
12 ;---------------------------;
13 fdd_int_done dw 0 ; is the IRQ done?
14 fdd_motor_on db 0 ; fdd motor on=1, off=0
15 fdd_drivehead db 0 ; ((head*4)|drive)
19 fdd_error db 0 ; should we recalibrate
24 result_ST1 db 0 ; or pcn
35 ;------------------------------------------------------;
36 ; initializes the floppy disk driver ;
38 ;------------------------------------------------------;
46 xor eax, eax ; get configuration
47 mov al, 0x10 ; from CMOS.
55 mov cl, 0x26 ; hook IRQ 6
60 mov cl, 6 ; enable IRQ6
63 call fdd_reset
; reset FDC
75 ;------------------------------------------------------;
78 ;------------------------------------------------------;
98 ;------------------------------------------------------;
99 ; wait for a floppy int ;
100 ; out: cf = 1 if timeout ;
101 ;------------------------------------------------------;
106 mov ecx, 150 ; 50 = 0.5 seconds.
107 call active_delay
; timer.inc
109 cmp dword [ecx], 0 ; timeup?
111 mov ax, [fdd_int_done
] ; if not we check for int.
126 ;------------------------------------------------------;
129 ;------------------------------------------------------;
131 cmp [fdd_motor_on
], 0
137 mov al, 0x0c ; motor off
139 mov [fdd_motor_on
], 0
148 ;------------------------------------------------------;
151 ;------------------------------------------------------;
153 cmp [fdd_motor_on
], 1
158 mov dx, 0x3F2 ; motor 0 on..
162 mov ecx, 20 ; 1/5 of a sec. to speed up
163 call delay
; in timer.inc
164 mov [fdd_motor_on
], 1
173 ;------------------------------------------------------;
174 ; send a data byte to the FDC ;
176 ; in: al = data byte ;
177 ;------------------------------------------------------;
183 mov ecx, 50 ; 50 = 0.5 seconds.
184 call active_delay
; timer.inc
186 cmp dword [ecx], 0 ; timeup?
188 mov dx, 0x3f4 ; check status reg
191 cmp al, 0x80 ; ok to write?
196 mov dx, 0x3F5 ; send byte
210 ;------------------------------------------------------;
211 ; read a data byte from the FDC ;
213 ; out: al = data byte ;
214 ;------------------------------------------------------;
220 mov ecx, 50 ; 50 = 0.5 seconds.
221 call active_delay
; timer.inc
223 cmp dword [ecx], 0 ; timeup?
225 mov dx, 0x3f4 ; check status reg
228 cmp al, 0xD0 ; ok to read?
233 mov dx, 0x3F5 ; get the byte
247 ;------------------------------------------------------;
248 ; sense interrupt status command ;
250 ;------------------------------------------------------;
254 mov al, 0x08 ; fdc command
257 mov ah, al ; save ST0 in ah
258 call fdc_getbyte
; read PCN
260 test ah, 0x80 ; test for error:
261 jz .end ; "invalid command"
269 ;------------------------------------------------------;
272 ;------------------------------------------------------;
278 mov byte [fdd_motor_on
], 0
281 mov al, 8 ; off with all motors,
282 out dx, al ; dma,irq etc..
285 call delay
; in timer.inc
289 out dx, al ; work at 500 kbit/s
293 out dx, al ; reenable interrupts
295 mov [fdd_int_done
], 0
296 call wait_int
; wait for floppy int.
300 .status: ; 4 dummy-reads.
304 mov al, 0x03 ; specify command
306 mov al, 0xDF ; SRT, HUT
308 mov al, 0x02 ; HLT, ND
328 ;------------------------------------------------------;
329 ; fdd_recal_seek - fdd recalibrate/seek ;
330 ;------------------------------------------------------;
332 ; in: al = 0 on seek, 1 on recalibrate ;
333 ; bl = (at seek) track ;
334 ; bh = (at seek) ((head*4)|drive) ;
336 ;------------------------------------------------------;
340 call fdd_on
; turn motor on
344 cmp bl, [result_C
] ; are we there yet? :D
346 mov al, 0x0F ; seek command
348 mov al, bh ; ((head*4)|drive)
352 mov [result_C
], bl ; now on..?
355 mov al, 0x07 ; recalibrate command
357 mov al, 0 ; drive number
359 mov [result_C
], 0 ; now on track 0
361 mov [fdd_int_done
], 0
365 call sensei
; sense interrupt status
378 ;------------------------------------------------------;
379 ; fdd_read_write - fdd read/write ;
380 ;------------------------------------------------------;
381 ; input: bl = 0 read, 1 write ;
382 ; ch = track/cylinder ;
385 ; edi = address to store or read the data ;
386 ; output: al = status ;
387 ; cf = 0 if ok, 1 if error ;
388 ;------------------------------------------------------;
392 and dh, 1 ; head 0 or 1?
393 mov [fdd_head
], dh ; store it.
395 or dh, 0 ; drive 0, fd0
396 mov [fdd_drivehead
], dh ; dh = ((head*4)|drive)
397 mov [fdd_errorcode
], 0x04 ; basic error code
398 cmp ch, 0x51 ; check for allowed
399 jae .error
; track number.
401 cmp cl, 0x13 ; check for allowed
402 jae .error
; sector number.
406 jne .no_previous_error
413 mov al, 0 ; 500Kb/sec mode
415 mov [fdd_errorcode
], 0x80 ; error code
418 mov cx, 3 ; try seek 3 times
423 mov bh, [fdd_drivehead
] ; ((head*4)|drive)
426 jnc .l3
; ok, continue.
428 jmp .error
; timeout.
437 mov edi, 0x80000 ; copy the stuff we will
438 mov ecx, 128 ; write to the DMA buffer
439 rep movsd ; 128*4=512
442 mov bl, 2 ; channel 2
443 mov esi, 512 ; bytes to write
444 mov ecx, 0x80000 ; page & offset
445 mov bh, 1 ; write floppy, read DMA
448 mov al, 0xC5 ; write sector command
453 mov bl, 2 ; channel 2
454 mov esi, 512 ; bytes to read
455 mov ecx, 0x80000 ; page & offset
456 mov bh, 0 ; read floppy, write DMA
459 mov al, 0xE6 ; read sector command
464 mov al, [fdd_drivehead
] ; ((head*4)|drive)
466 mov al, [fdd_track
] ; track/cylinder
469 mov al, [fdd_head
] ; head/side 0 or 1
471 mov al, [fdd_sector
] ; sector number
473 mov al, 0x02 ; sector size, 512 bytes
476 mov al, 0x12 ; sectors to a track
478 mov al, 0x1B ; gap length
480 mov al, 0xFF ; data length
483 mov [fdd_int_done
], 0
488 mov [result_ST0
], al ; ST0
490 mov [result_ST1
], al ; ST1
492 mov [result_ST2
], al ; ST2
494 mov [result_C
], al ; cylinder
496 mov [result_H
], al ; head
498 mov [result_R
], al ; sector number.
500 mov [result_N
], al ; sector size
502 test [result_ST0
], 0xc0 ; test if sr0 is 0xC0
504 cmp bl, 1 ; did we write the disk?
507 mov ecx, 512 ; sector size in bytes
508 mov esi, 0x80000 ; copy to dest. in edi
511 mov [fdd_errorcode
], 0 ; no error.. :D
512 mov [fdd_error
], 0 ; no recal. next time
516 mov [fdd_error
], 1 ; recalibrate next time
519 call fdd_off
; floppy motor off
521 mov al, [fdd_errorcode
] ; error status