]>
wirehaze git hosting - BOS.git/blob - kernel/fdc/fdc.asm
81b4997ae62a850c91c88de5418b71e7e00edad2
1 ;----------------------------------------------------------;
2 ; BOS kernel Christoffer Bubach, 2004-2005. ;
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
20 fdd_errorcode db 0 ; this the error code 00 = no error
21 fdd_tries db 0 ; no. of times to try, before error.
24 ResultST1 db 0 ; or pcn
35 ;------------------------------------------------------;
36 ; initializes the floppy disk driver ;
38 ;------------------------------------------------------;
43 mov cl, 0x26 ; hook interrupt 0x26 (IRQ6)
47 mov cl, 6 ; enable IRQ6
50 call fdd_reset
; reset FDC
59 ;------------------------------------------------------;
62 ;------------------------------------------------------;
85 ;------------------------------------------------------;
86 ; wait for a floppy int ;
87 ; out: cf = 1 if timeout ;
88 ;------------------------------------------------------;
93 mov ecx, 150 ; 150 = 1.5 seconds.
94 call active_delay
; timer.inc
96 cmp dword [ecx], 0 ; timeup?
98 mov ax, [fdd_int_done
] ; if not we check for int.
113 ;------------------------------------------------------;
116 ;------------------------------------------------------;
122 mov al, 0 ; all motors off..
124 mov [fdd_motor_on
], 0
133 ;------------------------------------------------------;
136 ;------------------------------------------------------;
141 mov dx, 0x3F2 ; motor 0 on..
145 mov ecx, 20 ; 1/5 of a sec. to speed up
146 call delay
; in timer.inc
147 mov [fdd_motor_on
], 1
155 ;------------------------------------------------------;
156 ; send a data byte to the FDC ;
158 ; in: al = data byte ;
159 ;------------------------------------------------------;
165 mov ecx, 150 ; 150 = 1.5 seconds.
166 call active_delay
; timer.inc
168 cmp dword [ecx], 0 ; timeup?
170 mov dx, 0x3f4 ; check status reg
173 cmp al, 10000000b ; are we ok to write
178 mov dx, 0x3F5 ; send byte
191 ;------------------------------------------------------;
192 ; read a data byte from the FDC ;
194 ; out: al = data byte ;
195 ;------------------------------------------------------;
201 mov ecx, 150 ; 150 = 1.5 seconds.
202 call active_delay
; timer.inc
204 cmp dword [ecx], 0 ; timeup?
206 mov dx, 0x3f4 ; check status reg
209 cmp al, 11000000b ; are we ok to read
214 mov dx, 0x3F5 ; get the byte
229 ;------------------------------------------------------;
232 ;------------------------------------------------------;
239 mov al, 00001000b ; no motors enabled, DMA Enabled, held FDC at reset
240 out dx, al ; drive A selected.
243 call delay
; in timer.inc
246 mov al, 00000000b ; 500Kb/sec mode
250 or al, 00001100b ; FDC completed reset, al =0x0c.
253 mov [fdd_int_done
], 0 ; we need to wait
254 call wait_int
; for floppy int.
255 jc .error
; jump to error exit, if timeout.
257 mov cx, 0x04 ; after a reset, the interrupts must be
258 .status: ; cleared by (four) dummy-reads.
259 mov al, 0x08 ; sense interrupt status command
265 mov al, 0x03 ; specify command (includes next two bytes sent)
267 mov al, 0xDF ; SRT = 3ms, HUT = 240ms
269 mov al, 0x02 ; HLT = 16ms, ND = 0
287 ;------------------------------------------------------;
290 ;------------------------------------------------------;
294 mov al, [ResultC
] ; put what track/cylinder we are at in al
295 cmp [fdd_track
], al ; is it the same as we want
296 je .ok
; yes, then leave.
298 mov al, 0x0F ; seek command
300 mov al, [fdd_driveno
] ; drive # (00 = A)
302 mov al, [fdd_track
] ; cylinder #
305 mov [fdd_int_done
], 0
309 mov al, 0x08 ; sense interrupt status command
312 mov ah, al ; save ST0 in ah
313 call fdc_getbyte
; should read PCN
315 test ah, 00100000b ; test sr0 is 0x20
316 jz .error
; if not we have a error :-(.
317 test ah,10000000b ; test sr0 is 0x80
318 jnz .error
; if not we have a error :-(.
319 .ok: ; succsess.. :-)
329 ;------------------------------------------------------;
332 ;------------------------------------------------------;
336 test [fdd_motor_on
], 1
340 mov al, 0x07 ; recalibrate command
342 mov al, 0x00 ; selects drive a:
345 mov [fdd_int_done
], 0
349 mov al, 0x08 ; sense interrupt status command
351 call fdc_getbyte
; read STO
352 mov ah, al ; save ST0 in ah
355 test ah, 00100000b ; test sr0 is 0x20
357 test ah, 00010000b ; test sr0 is 0x80
371 ;------------------------------------------------------;
373 ; input: bl = 0 read, 1 write ;
374 ; ch = track/cylinder ;
377 ; dl = drive (only A: drive used, 00 ) ;
378 ; output: ah = status ;
379 ; al = sector number read ;
380 ; cf = 0 if ok, 1 if error ;
381 ;------------------------------------------------------;
384 and dh, 00000001b ; is it set to fdd_head 0 or 1?
385 mov [fdd_head
], dh ; store it.
386 shl dh, 2 ; make the first 2 bits = 00 for A:.
387 mov [fdd_driveno
], dh ; store it.
389 mov [fdd_errorcode
], 0x04 ; put error code in ah, just incase
390 cmp ch, 0x51 ; cmp if track number, is above 80 decimal (51 hex)?
391 jae .error
; if above jump error.
392 mov [fdd_track
], ch ; if not above,store it.
394 cmp cl, 0x13 ; cmp if fdd_sector number, is above 18 decimal (12 hex) ?.
395 jae .error
; if above jump error.
396 mov [fdd_sector
], cl ; if not above,store it.
398 test [fdd_motor_on
], 1
403 mov al, 00000000b ; 500Kb/sec mode
405 mov [fdd_errorcode
], 0x80 ; put basic error code, just in case.
408 mov cx, 3 ; we want to try seek 3 times
410 call fdd_seek
; we need to move to the right track.
411 jnc .l3
; we should be on the right track.
413 jmp .error
; timeout.
415 mov dx, 0x3f4 ; check status reg (to see if DMA bit set)
417 test al, 00100000b ; test sr0 is 0x80
424 mov bl, 2 ; channel 2
425 mov esi, 512 ; bytes to write
426 mov ecx, 0x80000 ; page & offset
427 mov bh, 1 ; write floppy, "read DMA"
430 mov al, 0xC5 ; write fdd_sector command
435 mov bl, 2 ; channel 2
436 mov esi, 512 ; bytes to read
437 mov ecx, 0x80000 ; page & offset
438 mov bh, 0 ; read floppy, "write DMA"
441 mov al, 0xE6 ; read fdd_sector command
445 mov al, [fdd_driveno
] ; fdd_head no. 0, drive A:
447 mov al, [fdd_track
] ; cylinder
450 mov al, [fdd_head
] ; head/side 0 or 1
452 mov al, [fdd_sector
] ; sector number,starts at 1
454 mov al, 0x02 ; sector size - 512 bytes
457 mov al, 0x12 ; 18 decimal sectors to a track
459 mov al, 0x1B ; 27 should be the gap length for a 3.5" 1.44Mb
461 mov al, 0xFF ; not used data length, because sector size has been filled
464 mov [fdd_int_done
], 0
469 mov [ResultST0
], al ; save result of ST0 in var
471 mov [ResultST1
], al ; save result of ST1 in var
473 mov [ResultST2
], al ; save result of ST2 in var
475 mov [ResultC
], al ; save result of cylinder
477 mov [ResultH
], al ; save result of head
479 mov [ResultR
], al ; save result of sector number.
481 mov [ResultN
], al ; save result of sector size
483 test [ResultST0
], 11000000b ; test sr0 is 0xC0
485 mov [fdd_errorcode
], 0x00
488 mov ah, [fdd_errorcode
] ; move error status into ah
494 mov ah, [fdd_errorcode
] ; move error status into ah