[TUTORIAL]: How to read (and supposedly write) floppies.

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.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

Well I do it by waiting on a semaphore (which the scheduler provides) and posting to that semaphore from the interrupt handler.

I don't actually have irq_wait() anymore in my own kernel, since I needed explicit handlers for other stuff, so my floppy driver now explicitly waits on such a semaphore, and has an interrupt handler which simply posts to the semaphore in question.

If you don't have scheduler/multi-threading/semaphores you could simulate them by polling a (volatile) variable, which is then set by the interrupt handler. Just make sure you reset the variable to no-interrupt state before you do anything that could trigger an interrupt. That'll waste power, but you could drop a HLT into the polling loop (since you'll get woken from the HLT-state by every interrupt) to counter that.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

Post by urxae »

(I see mystran has beaten me to posting, but I'll put this up anyway)
piranha wrote:How do you write an IRQ_wait routine?

Do you have an example?
Mine simple implementation is basically:
- A counter (starts at 0)
- An IRQ handler that simply increments that counter.
- Another counter which keeps track of the last counter value waited for. This should ensure correct behavior in cases like a thread-switch occurring (or the hardware is unexpectedly fast) causing the IRQ to fire before IRQ_wait() gets executed. In my implementation, this is a static variable in IRQ_wait. It's incremented just before exiting from IRQ_wait.
- IRQ_wait itself then just loops until the counter is different. It should probably call yield() to schedule another thread while it waits, to avoid wasting CPU time waiting for the floppy that could be better spent doing useful stuff.

Don't forget the counters should be declared volatile if you're using C or C++ so the compiler isn't allowed to optimize out actually accessing them.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

urxae wrote: Mine simple implementation is basically:
- A counter (starts at 0)
- An IRQ handler that simply increments that counter.
- Another counter which keeps track of the last counter value waited for. This should ensure correct behavior in cases like a thread-switch occurring (or the hardware is unexpectedly fast) causing the IRQ to fire before IRQ_wait() gets executed. In my implementation, this is a static variable in IRQ_wait. It's incremented just before exiting from IRQ_wait.
- IRQ_wait itself then just loops until the counter is different. It should probably call yield() to schedule another thread while it waits, to avoid wasting CPU time waiting for the floppy that could be better spent doing useful stuff.
Actually one can get away with even more simple implementation, for which you only need one bit flag: as long as you make sure to clear the flag before you start an operation which could cause an interrupt, you only need to wait until the interrupt handler sets the flag. All interrupts you should get in your floppy handler should be known beforehand, so the only potential race-condition would be when the interrupt comes before you cleared the flag. If the flag is cleared when the interrupting operation is started, there should be little to worry about, unless you want to prepare for the possibility of getting interrupts which have nothing to do with the floppy drive.

Anyway, you should probably consider using a semaphores instead, since then you don't need to loop/yield anything, because you get scheduled only when something happens (timeout or post()). If you don't have semaphores, I suggest you implement them, as they are very nice for building all kinds of more advanced synchronization primitives, and very flexible, allowing you to easily come up with different policies.

My floppy driver's interrupt handler actually checks that the semaphore is zero (using trywait(), the non-blocking wait(), until it returns with an error indicating that wait() would block) before post()ing, so that the value of the semaphore will never be more than one. That way I make sure that at least extra interrupts will never accumulate; in the worst case they confuse the driver, which then has to reset the drive to recover a known state.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

I replied to this post already once, but obviously forgot to reply to some points. So here comes another reply.
Now, in the following document it says nothing about recalibration, maybe it's wrong and the cause of why my driver locks up:
I hope you aren't relying on the BIOS bit part, because that will only work in real-mode, and even then only if you don't touch the interrupt handler.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
User avatar
XCHG
Member
Member
Posts: 416
Joined: Sat Nov 25, 2006 3:55 am
Location: Wisconsin
Contact:

Post by XCHG »

I have found a very useful HTML page that explains almost everything about Floppy Disk Controllers. I hope that it will be of some use to you guys.

Okay, since we can't attach files bigger than 64KB in this forum so I uploaded the tutorial in my web-site. Download Link:

http://www.ASMTrauma.com/FloppyProgramming.zip
On the field with sword and shield amidst the din of dying of men's wails. War is waged and the battle will rage until only the righteous prevails.
User avatar
~
Member
Member
Posts: 1227
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Post by ~ »

XCHG wrote:I have found a very useful HTML page that explains almost everything about Floppy Disk Controllers. I hope that it will be of some use to you guys.

Okay, since we can't attach files bigger than 64KB in this forum so I uploaded the tutorial in my web-site. Download Link:

http://www.ASMTrauma.com/FloppyProgramming.zip
http://didactos.blogsyte.com/disks

By the way, sorry, I was having problems with my network, but I think now there will be a good uptime. So I also post my address, in which you will find a little bit more of information and a source code demo (specially for MS-DOS/Win) in the file floppy.zip.
User avatar
Bonfra
Member
Member
Posts: 270
Joined: Wed Feb 19, 2020 1:08 pm
Libera.chat IRC: Bonfra
Location: Italy

Re: [TUTORIAL]: How to read (and supposedly write) floppies.

Post by Bonfra »

maby a bit late but is this now a part of the wiki? if yes where?
Regards, Bonfra.
itsmevjnk
Member
Member
Posts: 32
Joined: Fri Apr 13, 2018 10:18 am
Location: Melbourne, VIC, Australia

Re: [TUTORIAL]: How to read (and supposedly write) floppies.

Post by itsmevjnk »

Bonfra wrote:maby a bit late but is this now a part of the wiki? if yes where?
I don't think so, though the wiki article for floppy points to this: https://wiki.osdev.org/Floppy_Disk_Cont ... orum_Posts
Also, why are you reviving a necrothread from >10 years ago?
Just a procrastinating uni student doing stupid things (or not doing them at all)...

SysX: https://github.com/itsmevjnk/sysx.git
Viacheslav
Posts: 7
Joined: Tue Jun 06, 2023 9:37 am

Re:

Post by Viacheslav »

anon19287473 wrote:Is there a C compiler that compiles into NASM?
Do you mean gcc with -masm=intel flag? You could also compile normally to object file and run "objdump -S -Mintel"
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: Re:

Post by Octocontrabass »

Viacheslav wrote:Do you mean gcc with -masm=intel flag? You could also compile normally to object file and run "objdump -S -Mintel"
You're replying to a post from 16 years ago, written by someone who last logged in 16 years ago. Please check the date on the post before replying. (Also, Intel syntax is not the same as NASM syntax.)
Post Reply