Why i can only read 2 times by my floppy driver?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
iamxiaohan

Why i can only read 2 times by my floppy driver?

Post by iamxiaohan »

hi,i encounter a very strange problem. i write a floppy driver, but i only use it 2 times. if i want read any more, it can't work. i don't know why. can you help me? thank you!
the following is my some code.
============================
void floppy_read( unsigned char sector , unsigned char cylinder , unsigned char head )
{
floppy_reset() ;

floppy_seek_cylinder( head , cylinder ) ;

dma_open_dma_channel( 2 , floppy_buffer_address , 512 , DMA_READ_MODEL ) ;

floppy_send_byte_return_is_ok( 0x66 ) ;
floppy_send_byte_return_is_ok( head << 2 ) ;
floppy_send_byte_return_is_ok( cylinder ) ;
floppy_send_byte_return_is_ok( head ) ;
floppy_send_byte_return_is_ok( sector ) ;
floppy_send_byte_return_is_ok( 2 ) ;
floppy_send_byte_return_is_ok( 18 ) ;
floppy_send_byte_return_is_ok( 27 ) ;
floppy_send_byte_return_is_ok( 255 ) ;

floppy_wait_for_interrupt() ;
}

void floppy_reset()
{
io_write_to_io_port( 0x3f2 , 0 ) ;
io_write_to_io_port( 0x3f2 , 0x1c ) ;
floppy_wait_for_interrupt() ;
for( int i = 0 ; i < 4 ; ++i ){
floppy_read_status() ;
}
floppy_set_specification() ;
floppy_recalibrate() ;
}

void kernel_main()
{
.....
floppy_read( 1 , 0 , 0 ) ; // well
floppy_read( 2 , 0 , 0 ) ; // well
floppy_read( 3 , 0 , 0 ) ; // bad! this statement doesn't work, but why???
....
}
iamxiaohan

Re:Why i can only read 2 times by my floppy driver?

Post by iamxiaohan »

btw: i test it on bochs 2.11
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:Why i can only read 2 times by my floppy driver?

Post by Brendan »

Hi,
iamxiaohan wrote: btw: i test it on bochs 2.11

What do you get for the results of the read data command, most specifically, ST0, ST1 and ST2?

These results should be read when the IRQ is received - they contain flags that say if the command worked (and if it didn't why it didn't work).

BTW you shouldn't need to reset the floppy drive controller every time you read some data...


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
ASHLEY4

Re:Why i can only read 2 times by my floppy driver?

Post by ASHLEY4 »

Here are my thought, i have just made a floppy driver, but in asm, i do not use C, but what i can read between the lines your looks the same as mine, but for two things.
you send 0x66, i send 0xe6, also to me you must read 7 bytes after the interrupt, i do not know if it makes a differenc, but is does on the reset command, so maybe it needs it on the read sector ?

Or may be its boch giving you a hard time, have you tryed it in a real pc ?.

ps: i have not got my floppy code with me so above is from memory.

\\\\||////
(@@)
ASHLEY4.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:Why i can only read 2 times by my floppy driver?

Post by Brendan »

Hi,
ASHLEY4 wrote: you send 0x66, i send 0xe6, also to me you must read 7 bytes after the interrupt, i do not know if it makes a differenc, but is does on the reset command, so maybe it needs it on the read sector ?
The difference between 0x66 and 0xE6 is the MT (multi-track) bit, which shouldn't matter as only one track is being read.

There is a bug I didn't notice - commands are being sent to read sectors 1 to 18, then sectors 2 to 18, then sectors 3 to 18, but the DMA transfer is set up to only read a single sector. Because of this the read commands should all fail (Overrun/Underrun bit set in ST1) after transferring one sector. From this I assume that the status bytes are not read (or are read and ignored), and the first 2 reads are assumed to have worked because one sector is read.

Also there doesn't seem to be anything turning the floppy motor on (or off). This might be done within "floppy_recalibrate()" or something.

The 7 status bytes might also be read within "floppy_wait_for_interrupt()" or in the IRQ handler (although I can't see how either of these can know how many bytes to expect, unless it's hard-coded which would make things harder when other floppy commands are added).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply