Floppys again
Floppys again
Finally I think I?ve written som good floppy/dma code. But there are some things I dont know what to chose (I just wanna use a regular 1.4 floppy). When sending the fix drive data command, what values should I chose on Step rate, head unlock time and head load time?
Re:Floppys again
For some reason, the IRQ after I?ve tried to read a sector does not fire. I?ve attached my code for the floppy and the dma, it isn?t very much code and Im sure someone who has done this before has no problems to understand it, if someone?d like to help me, been stuck with all the floppy-stuff for a while and I suppose it doesnt take much to fix it.
What I try to achieve is simple to allocate some memory (the memory manager works), and read the first sector (512 bytes) from the "floppy A" and save it in the allocated space
What I try to achieve is simple to allocate some memory (the memory manager works), and read the first sector (512 bytes) from the "floppy A" and save it in the allocated space
Re:Floppys again
Hi,
These are your original values (comments added/adjusted for reference purposes):
The read data command (line A) is command 0x06 (not '3' which is the specify command), but it has a few other bits. The MT flag (multi-track) won't matter as you're only reading one sector. The MFM bit should be set for double density media (1440 Kb), and the SK bit should be set to skip deleted sectors.
Lines B, C and D are correct.
Line E is the sector number which should be between 1 and 18, as sector 1 is the first sector (confusing because cylinder 0 is the first cylinder).
Line F is messed up, and I really wish that compilers would give warnings when you try to store large constants in small variables. Basically this "sector size code" is not the number of bytes in the sector (which doesn't fit in a byte), but is a code from this table:
0x00 = 128 byte sectors
0x01 = 256 byte sectors
0x02 = 512 byte sectors
0x03 = 1024 byte sectors
0x04 = 2048 byte sectors
...
0x07 = 16384 byte sectors
You'd want 512 byte sectors, so you should be using 2.
Line H sets the gap length, which should be 0x1B for reading and writing to/from 1440Kb floppies. For formatting you'd use 0x54. Because 42 is lower than 0x54 it'd probably work most of the time..
Line I is used to specify how many bytes to transfer if 128 byte sectors are being used. You're not using 128 bytes sectors, from the manual: "When N [the sector size code] is not zero [or set for 128 bytes], DTL has no meaning and should be set to FF HEX."
So, taking everything above into account:
Cheers,
Brendan
These are your original values (comments added/adjusted for reference purposes):
Code: Select all
fdc_send_command(3); // A: MT, MFM, SK, Read data command
fdc_send_command(0); // B: Head & drive
fdc_send_command(0); // C: Cylinder
fdc_send_command(0); // D: Head again
fdc_send_command(0); // E: Sector Number
fdc_send_command(512); // F: Sector size code
fdc_send_command(1); // G: EOT
fdc_send_command(42); // H: GPL
fdc_send_command(512); // I: DTL Data Length
Lines B, C and D are correct.
Line E is the sector number which should be between 1 and 18, as sector 1 is the first sector (confusing because cylinder 0 is the first cylinder).
Line F is messed up, and I really wish that compilers would give warnings when you try to store large constants in small variables. Basically this "sector size code" is not the number of bytes in the sector (which doesn't fit in a byte), but is a code from this table:
0x00 = 128 byte sectors
0x01 = 256 byte sectors
0x02 = 512 byte sectors
0x03 = 1024 byte sectors
0x04 = 2048 byte sectors
...
0x07 = 16384 byte sectors
You'd want 512 byte sectors, so you should be using 2.
Line H sets the gap length, which should be 0x1B for reading and writing to/from 1440Kb floppies. For formatting you'd use 0x54. Because 42 is lower than 0x54 it'd probably work most of the time..
Line I is used to specify how many bytes to transfer if 128 byte sectors are being used. You're not using 128 bytes sectors, from the manual: "When N [the sector size code] is not zero [or set for 128 bytes], DTL has no meaning and should be set to FF HEX."
So, taking everything above into account:
Code: Select all
fdc_send_command(0x66); // A: MT, MFM, SK, Read data command
fdc_send_command(0); // B: Head & drive
fdc_send_command(0); // C: Cylinder
fdc_send_command(0); // D: Head again
fdc_send_command(1); // E: Sector Number
fdc_send_command(0x02); // F: Sector size code
fdc_send_command(1); // G: EOT
fdc_send_command(0x1B); // H: GPL
fdc_send_command(0xFF); // I: DTL Data Length
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.
Re:Floppys again
Thanks Brendan, what should I do without you?
I found another problem in my DMA code (which I believe is pretty correct but I haven?t tested it, didnt found a way to test it without trying to use it for the floppy-stuff). I think it?s something about the "mode" that?s wrong because now, when I use the code that you wrote, Bochs says
"hlda: transfer_type 3 is undefined"
Edit: I forgot to disable/enable interrupts when programming the DMA, it?s fixed now. But I dont get no floppy interrupt that tells me thatthe transfer is done. So there must be something wrong either with my DMA code or with the floppy initialization (really didnt care about the head lock time and all that, the values are in my code).
And one thing is weird. When I try to read the virtual floppy, my bootloader/kernel-floppy is still inserted (which mean that I try to read my boot loader), but the code changes this! If I start the kernel and run it(with the floppy code), and then try to reload the OS file, bochs says that it?s no bootable floppy, which means that my floppy code changes something in the first sector(and it?s only supposed to read, but that doesnt work either)
I found another problem in my DMA code (which I believe is pretty correct but I haven?t tested it, didnt found a way to test it without trying to use it for the floppy-stuff). I think it?s something about the "mode" that?s wrong because now, when I use the code that you wrote, Bochs says
"hlda: transfer_type 3 is undefined"
Edit: I forgot to disable/enable interrupts when programming the DMA, it?s fixed now. But I dont get no floppy interrupt that tells me thatthe transfer is done. So there must be something wrong either with my DMA code or with the floppy initialization (really didnt care about the head lock time and all that, the values are in my code).
And one thing is weird. When I try to read the virtual floppy, my bootloader/kernel-floppy is still inserted (which mean that I try to read my boot loader), but the code changes this! If I start the kernel and run it(with the floppy code), and then try to reload the OS file, bochs says that it?s no bootable floppy, which means that my floppy code changes something in the first sector(and it?s only supposed to read, but that doesnt work either)
Re:Floppys again
Hi,
So based on all this, you'd be setting the DMA as:
Channel = 2
Operation = Reserved
Autoinitialization disabled
Direction = Increment address
Transfer mode = demand mode
My floppy code uses:
Channel = 2
Operation = write to memory (read from memory if writing data to disk)
Autoinitialization disabled
Direction = Increment address
Transfer mode = single mode
This would be 01001001b (or 0x49, or 73).
Cheers,
Brendan
Well I guess we better look at the mode you're setting, which is 14 (or 0x0E or 00001110b). My docs say:Brandon wrote: I found another problem in my DMA code (which I believe is pretty correct but I haven?t tested it, didnt found a way to test it without trying to use it for the floppy-stuff). I think it?s something about the "mode" that?s wrong because now, when I use the code that you wrote, Bochs says
"hlda: transfer_type 3 is undefined"
Code: Select all
7-6 transfer mode
00 demand mode
01 single mode
10 block mode
11 cascade mode
5 direction
0 increment address after each transfer
1 decrement address
4 autoinitialization
0 autoinitialization disabled
1 autoinitialization enabled
3-2 operation
00 verify operation
01 write to memory
10 read from memory
11 reserved
1-0 channel number
00 channel 0 select
01 channel 1 select
10 channel 2 select
11 channel 3 select
Channel = 2
Operation = Reserved
Autoinitialization disabled
Direction = Increment address
Transfer mode = demand mode
My floppy code uses:
Channel = 2
Operation = write to memory (read from memory if writing data to disk)
Autoinitialization disabled
Direction = Increment address
Transfer mode = single mode
This would be 01001001b (or 0x49, or 73).
Bochs doesn't worry about the head load time, etc either so I'd probably get the rest working under Bochs before worrying much about them. When you do get it working under Bochs you'll want to set them properly - I saw a post on this board that gave full details for the arguments of the specify command (and formulas for calculating them for all circumstances). It's about the 3rd message from the bottom here: http://www.mega-tokyo.com/forum/index.p ... 5;start=30Brandon wrote: Edit: I forgot to disable/enable interrupts when programming the DMA, it?s fixed now. But I dont get no floppy interrupt that tells me that the transfer is done. So there must be something wrong either with my DMA code or with the floppy initialization (really didnt care about the head lock time and all that, the values are in my code).
Not sure why this'd happen (it shouldn't as far as I can tell).Brandon wrote: And one thing is weird. When I try to read the virtual floppy, my bootloader/kernel-floppy is still inserted (which mean that I try to read my boot loader), but the code changes this! If I start the kernel and run it(with the floppy code), and then try to reload the OS file, bochs says that it?s no bootable floppy, which means that my floppy code changes something in the first sector(and it?s only supposed to read, but that doesnt work either)
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.
Re:Floppys again
As far as I know this is more a bug in Bochs. It only occures when it crashed(aka buggy) (sometimes).Brandon wrote: And one thing is weird. When I try to read the virtual floppy, my bootloader/kernel-floppy is still inserted (which mean that I try to read my boot loader), but the code changes this! If I start the kernel and run it(with the floppy code), and then try to reload the OS file, bochs says that it?s no bootable floppy, which means that my floppy code changes something in the first sector(and it?s only supposed to read, but that doesnt work either)
Had this sometimes too with Bochs :-\
Re:Floppys again
Brendan: It still does not work, the code gets stuck when I wait for the fdc irq to be fired. Is this really everything I have to do when reading a sector?:
start the motor
calibrate the device
do a seek to the right cylinder
send the commands for reading a sector
?
start the motor
calibrate the device
do a seek to the right cylinder
send the commands for reading a sector
?
Re:Floppys again
Hi,
I guess it's time to bring out the big guns. Do you remember when you start Bochs you get that annoying menu thing? Using this menu you can tell Bochs to report everything that happens, but my version of Bochs (2.1.1) seems a bit buggy - it doesn't seem to work when you enable reporting for individual devices (but it does let you disable reporting). I'll explain how I do it.
From the first menu select '3' (Edit Options), then '4' (Log options for all devices). Then it asks for the action for DEBUG events - type in "report". Then it asks for the action for INFO events, ERROR events, PANIC events and PASS events - for each of these just press enter (leave them unchanged).
At this point you can start bochs and quickly get a massive "bochsout.txt" full of unwanted information. To minimize this select '5' in the edit options menu (Log options for individual devices), and disable reporting for as much as you can (the PIT is a good start). To do this enter the number for the device (e.g. '16' for PIT) then type "ignore" for DEBUG events. You can do this for everything, but leave IO, SYS, STAT and DEV set to "report".
Now start Bochs running (you'll still get a huge "bochsout.txt"). Do anything you can to get your floppy code running as quickly as possible, and stop bochs as soon as it's completed.
Now you can check the log ("bochsout.txt"). I'd use cut & paste to shift all the DMA, FDC and PIC lines to a different file. You'd end up with a file containing stuff like:
All you need to do now is check what each line is doing (check what the FDC/DMA manual says will happen for each line you've got, including what each bit represents). You can also cut & paste the results from when Boch's BIOS loads your OS from floppy and compare it to your own...
Cheers,
Brendan
I guess it's time to bring out the big guns. Do you remember when you start Bochs you get that annoying menu thing? Using this menu you can tell Bochs to report everything that happens, but my version of Bochs (2.1.1) seems a bit buggy - it doesn't seem to work when you enable reporting for individual devices (but it does let you disable reporting). I'll explain how I do it.
From the first menu select '3' (Edit Options), then '4' (Log options for all devices). Then it asks for the action for DEBUG events - type in "report". Then it asks for the action for INFO events, ERROR events, PANIC events and PASS events - for each of these just press enter (leave them unchanged).
At this point you can start bochs and quickly get a massive "bochsout.txt" full of unwanted information. To minimize this select '5' in the edit options menu (Log options for individual devices), and disable reporting for as much as you can (the PIT is a good start). To do this enter the number for the device (e.g. '16' for PIT) then type "ignore" for DEBUG events. You can do this for everything, but leave IO, SYS, STAT and DEV set to "report".
Now start Bochs running (you'll still get a huge "bochsout.txt"). Do anything you can to get your floppy code running as quickly as possible, and stop bochs as soon as it's completed.
Now you can check the log ("bochsout.txt"). I'd use cut & paste to shift all the DMA, FDC and PIC lines to a different file. You'd end up with a file containing stuff like:
Code: Select all
d[DMA ]00000510 write: address=0005 value=01
d[DMA ]00000510 DMA-1 base and current count, channel 2
d[DMA ]00000510 base = 01ff
d[DMA ]00000510 curr = 01ff
d[DMA ]00000510 write: address=000b value=46
d[DMA ]00000510 DMA-1: mode register[2] = 46
d[DMA ]00000510 write: address=0081 value=00
d[DMA ]00000510 DMA-1: page register 2 = 00
d[DMA ]00000510 write: address=000a value=02
d[DMA ]00000510 DMA-1: set_mask_bit=0, channel=2, mask now=00h
d[DMA ]00000510 write: address=000a value=02
d[DMA ]00000510 DMA-1: set_mask_bit=0, channel=2, mask now=00h
d[FDD ]00000510 io_write: digital output register
d[FDD ]00000510 motor on, drive1 = 0
d[FDD ]00000510 motor on, drive0 = 1
d[FDD ]00000510 dma_and_interrupt_enable=08
d[FDD ]00000510 normal_operation=04
d[FDD ]00000510 drive_select=00
d[FDD ]00000510 command = e6
d[FDD ]00000510 io_write: diskette controller data
d[FDD ]00000510 command = 00
d[FDD ]00000510 io_write: diskette controller data
d[FDD ]00000510 command = 00
d[FDD ]00000510 io_write: diskette controller data
d[FDD ]00000510 command = 00
d[FDD ]00000510 io_write: diskette controller data
d[FDD ]00000510 command = 01
d[FDD ]00000510 io_write: diskette controller data
d[FDD ]00000510 command = 02
d[FDD ]00000510 io_write: diskette controller data
d[FDD ]00000510 command = 00
d[FDD ]00000510 io_write: diskette controller data
d[FDD ]00000510 command = 00
d[FDD ]00000510 io_write: diskette controller data
d[FDD ]00000510 command = ff
d[FDD ]00000510 FLOPPY COMMAND:
d[FDD ]00000510 [e6]
d[FDD ]00000510 [00]
d[FDD ]00000510 [00]
d[FDD ]00000510 [00]
d[FDD ]00000510 [01]
d[FDD ]00000510 [02]
d[FDD ]00000510 [00]
d[FDD ]00000510 [00]
d[FDD ]00000510 [ff]
d[FDD ]00000510 read/write normal data
d[FDD ]00000510 BEFORE
d[FDD ]00000510 drive = 0
d[FDD ]00000510 head = 0
d[FDD ]00000510 cylinder = 0
d[FDD ]00000510 sector = 1
d[FDD ]00000510 eot = 0
d[FDD ]00000510 io_write: diskette controller data
d[PIC ]00007c58 IRQ line 6 now high
d[PIC ]00007c58 signalling IRQ(6)
d[PIC ]000094a8 IO write to 0020 = 20
d[PIC ]000004f6 IRQ line 6 now low
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.
Re:Floppys again
I got a file with a size of lots and lots of megabytes? This?ll take time thank you I?ll try to work it out