Hi,
I am working on the FDC driver for my OS and it is not going on very well. I have included the full OS pack in the attachment. The DMA module sets up DMA channel 2 with offset 7000h (like SolarOs :) ). And the floppy.asm contsains all the other FDC crap. I also made a command 'fdc' in the kernel. It should read sector 13 and display it on the screen. I have written a text file to this sector. But it is not working. I think I should work on rebuilding it again. Maybe then it will work. Can someone have a look at it?
Thomas Antony
[attachment deleted by admin]
These are a few things I noticed when I looked through your code.
I don't know if it will fix things, but it will definitely help ;)
You might want to try not writing so much in one go, so you can test each bit and make sure it works first before adding another bit - it makes errors a lot easier to find too.
If you need more help, let me know and I'll take a better look :U
typo?
@fdc_w1:
mov edx,FDC_MSR
xor eax,eax
in al,dx
and al,08h ;<---- should be 80h ::)
jz @fdc_w2
guess what you missed
FDC_ReadWrite:
.
.
.
mov eax,[ebp+18h] ; send track
call FDC_WriteByte
hint: PUSH EAX :wink
--------------------------------
*not errors, just advice :)
- no need to CLI at start of an int handler - it's already done automatically
- and STI is done automatically on IRET
- when waiting for irq, you can use HLT in the wait loop (helps cool cpu, if nothing else)
Hi,
I finally got it to work myself. The next release of my Os is online :8) Get it at http://www.tomasm.tk
Thomas Antony
Quote- and STI is done automatically on IRET
While this may frequently be the apparent action, an IRET does not actually do an STI. Instead, it restores the state of the interrupt flag to what it was before the interrupt. From the Intel Architecture and Programming Manual:
Quote
INT/INTO -- Call to Interrupt Procedure
...
Operation
NOTE: The following operational description applies not
only to the aboove instructions but also to external
interrupts and exceptions.
IF PE = 0
THEN CALL REAL-ADDRESS-MODE;
...
REAL-ADDRESS-MODE PROC
Push(FLAGS);
IF <- 0 ;(* Clear interrupt flag *)
TF <- 0 ;(* Clear trap flag *)
AC <- 0 ;(* Clear AC flag *)
Push(CS);
Push(IP);
(* No error coded are pushed *)
CS <- IDT(interrupt number * 4).selector;
IP <- IDT(interrupt number * 4).offset;
(* Start ececution in real address mode *)
REAL-ADDRESS-MODE ENDPROC
...
IRET/IRETD -- Interrupt Return
...
Operation
IF PE = 0
THEN GOTO REAL_ADDRESS_MODE;
...
REAL_ADDRESS_MODE;
IF OperandSize = 32 (* Instruction = IRETD *)
THEN EIP <- Pop();
ELSE (* Instruction = IRET *)
IP <- Pop();
FI;
CS <- Pop();
IF OperandSize = 32 (* Instruction = IRETD *)
THEN EFLAGS <- Pop();
ELSE (* Instruction = IRET *)
FLAGS <- Pop();
FI;
END;
Hi MichealW, Thanx for the info
and Tedd, I didn't read your post properly last time as I was over the moon :dance:. If I did use HLT would the CPu execute the other instructions? If it does, how do I get out of this halt state. Is there a specific instruction to do this? Suppose I don't want a loop then. The CPU will halt until an IRQ is received right?
Thomas Antony
The cpu will HaLT until any interrupt is received and then just carry on to the next instruction (so you don't need to do an instruction to get out of HLT.)
IRQs have to come in through interrupts, so when you get an irq, the HLT will finish and the next instruction will be executed. The problem is that you don't know WHICH interrupt you got - it might not be the one you're waiting for - so you still have to check; it just means you're only checking after you actually get an interrupt and not all the time. You just have to make sure that ints aren't disabled when you do hlt though, otherwise you'll be waiting forever :bdg (But if you're expecting an irq, then ints shouldn't be disabled anyway.)
So you still need to check your flag to see if your irq handler was called, but the hlt is just there so you're not checking over and over when there's no need.
Unfortunately, the code has to go something like this:
;check before, just in case (unlikely, but technically possible)
mov eax,[irq_done]
test eax,eax
jnz @done
;the real wait loop
@wait_more:
hlt
mov eax,[irq_done]
test eax,eax
jz @wait_more
@done:
MichaelW: yeah yeah :P I wasn't quite as accurate as I could've been.
Hi,
I can't use hlt in my case as I am always reeiving timer interrupts also
Thomas Antony
I think your timer interrupt is 18.2 times per second(?)
This isn't very often for a computer running at millions of cycles per second.
The actual time you'll be waiting for floppy irq will only be milliseconds, so it's unlikely you'll get more than one timer interrupt.
So it's still a good thing to do :U