problem with my floppy driver in pmode
problem with my floppy driver in pmode
hello every body,
sorry for my bad english, I'm moroccan...
my question is : does any one already developped a floppy disk driver for pmod, my code seems to work with bochs & vmware, but not in a real PC ??!
it seems that when running in real PC the FDC cant fire IRQ6 coze it enter an infinite loop when it run this code
....
called=0;
while (!called);
...
called is set to 1 by IRQ6
can any one helps me ???
sorry for my bad english, I'm moroccan...
my question is : does any one already developped a floppy disk driver for pmod, my code seems to work with bochs & vmware, but not in a real PC ??!
it seems that when running in real PC the FDC cant fire IRQ6 coze it enter an infinite loop when it run this code
....
called=0;
while (!called);
...
called is set to 1 by IRQ6
can any one helps me ???
Re:problem with my floppy driver in pmode
is the variable volatile?
Re:problem with my floppy driver in pmode
called is declared as follow :
static int called=0;
but i can't understand why it worke well with bochs and not in a real PC.
static int called=0;
but i can't understand why it worke well with bochs and not in a real PC.
Re:problem with my floppy driver in pmode
We can help you better if we can see the code.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:problem with my floppy driver in pmode
a variable that is modified by some interrupt handler and looked up by 'regular' code *must* be declared 'volatile' to work properly ...
If you just have
the compiler can detect that 'flag' isn't touched by the body of the loop and thus optimize it as
which will obviously be wrong.
tells the CPU that the memory location for 'flag' is succeptible to change without the code generated by the compiler access it for writing, and thus forces the compiler to re-read the value from memory everytime a new access is performed (no register-caching will be allowed either).
If you just have
Code: Select all
static int flag;
void isr_handler() { flag = 1; }
void some_code() {
flag=0;
prepare_hardware();
while(!flag);
get_results();
}
Code: Select all
void some_code'() {
flag = 0;
...
if (!flag) while(1);
get_result();
}
Code: Select all
volatile int flag;
Re:problem with my floppy driver in pmode
this is my source code
#include <sys.h>
#include <floppy.h>
#define DL 128 //wait delay
char * floppy_type[] =
{
"Non install\202e",
"360Ko 5.25\"",
"1.2Mo 5.25\"",
"720Ko 3.5\"",
"1.44Mo 3.5\"",
"2.88Mo 3.5\""
};
volatile unsigned int called=0;
char buffer[512];
void detect_floppy()
{
unsigned char c;
printk(" Lecteurs de disquettes :\n");
outb(0x70, 0x10); //On demande au CMOS le type de la disquette
c = inb(0x71);
printk(" Lecteure A : %s\n",floppy_type[c >> 4]); //les 4 bits de poid fort contiennent le type de A:
printk(" Lecteure B : %s\n",floppy_type[c & 0xF]); //les 4 bits de poid faible contiennent le type de B:
}
void floppy_int()
{
//printk("\nFD_IRQ\n");
called=1;
return;
}
void fdmotor_off()
{
outb(FD_DOR, 0);
return;
}
void fdmotor_on()
{
//printk("FD motor on\n");
outb(FD_DOR, 0x1C);
called=0;
while(!called);
delay(DL);
return;
}
void fd_reset()
{
outb(FD_DOR, 0);
outb(FD_DOR, 0x0C);
outb(FD_DCR, 0); //
fd_cmd(0x03);
fd_cmd(0xdf);
fd_cmd(0x02);
fd_recalib();
called=0;
while(!called);
return;
}
int fd_recalib()
{
//printk("FD recalib\n");
fd_cmd(FD_RECALIBRATE);
fd_cmd(0);
delay(DL);
}
void fd_status()
{
char * status[] = {
"floppy drive 0 in seek mode/busy",
"floppy drive 1 in seek mode/busy",
"floppy drive 2 in seek mode/busy",
"floppy drive 3 in seek mode/busy",
"FDC read or write command in progress",
"FDC is in non-DMA mode",
"I/O direction; 1 = FDC to CPU; 0 = CPU to FDC",
"data reg ready for I/O to/from CPU (request for master)"};
int st=inb(FD_STATUS);
int i;
for (i=0; i<8; i++)
{
if (st & (1 << i)) {
???printk("test %d == %x\n", i, 1<<i);
???printk("%s\n",status);
}
}
}
static int fd_wait()
{
int st, i;
for (i=0; i<10000; i++)
{
st=inb(FD_STATUS);
if (st == STATUS_READY) return st;
}
return -1;
}
static int fd_cmd(unsigned char cmd)
{
outb(FD_DATA, cmd);
}
int fd_seek(unsigned char trk)
{
//printk("FD seek\n");
fd_cmd(FD_SEEK);
fd_cmd(0);
fd_cmd(trk);
called=0;
while(!called);
}
void setDMA()
{
//printk("Setting DMA\n");
cli;
outb(0xa,0x6);
outb(0xc,0);
outb(0x4,0);
outb(0x4,0);
outb(0xc,0);
outb(0x5,0xFF);
outb(0x5,0x1);
outb(0xb,0x46);
outb(0x81,0x8);
outb(0xa,0x2);
outb(0xa,0x2);
sti;
}
int fd_read() //read test of linear sector 0
{
fdmotor_on();
//outb(0x3f7, 0); //
fd_seek(0);
//delay(DL);
setDMA();
fd_cmd(FD_READ);
fd_cmd(0);
fd_cmd(0);
fd_cmd(0);
fd_cmd(1);
fd_cmd(2);
fd_cmd(18);
fd_cmd(0x1B);
fd_cmd(0xFF);
called=0;
while (!called);
printk("ST0 %x \n",inb(FD_DATA));
printk("ST1 %x \n",inb(FD_DATA));
printk("ST2 %x \n",inb(FD_DATA));
printk("Cyl %x \n",inb(FD_DATA));
printk("Hd %x \n",inb(FD_DATA));
printk("Sct %x \n",inb(FD_DATA));
printk("NBS %x \n",inb(FD_DATA));
memcpy(0x80000, buffer, 512);
fdmotor_off();
}
void print_fd_buffer()
{
int i;
for (i=0;i<512; i++)
{
printk("%x ",buffer&0x000000FF);
}
}
I detected another problem :
when I read a sector using fd_read() under bochs or vmware, all register status are OK but the first byte in my buffer is 0 (it must be 0xe9) this is about emulators...
now when I run this on a real PC the status register 0 is 0x80 (invalid command) ???
#include <sys.h>
#include <floppy.h>
#define DL 128 //wait delay
char * floppy_type[] =
{
"Non install\202e",
"360Ko 5.25\"",
"1.2Mo 5.25\"",
"720Ko 3.5\"",
"1.44Mo 3.5\"",
"2.88Mo 3.5\""
};
volatile unsigned int called=0;
char buffer[512];
void detect_floppy()
{
unsigned char c;
printk(" Lecteurs de disquettes :\n");
outb(0x70, 0x10); //On demande au CMOS le type de la disquette
c = inb(0x71);
printk(" Lecteure A : %s\n",floppy_type[c >> 4]); //les 4 bits de poid fort contiennent le type de A:
printk(" Lecteure B : %s\n",floppy_type[c & 0xF]); //les 4 bits de poid faible contiennent le type de B:
}
void floppy_int()
{
//printk("\nFD_IRQ\n");
called=1;
return;
}
void fdmotor_off()
{
outb(FD_DOR, 0);
return;
}
void fdmotor_on()
{
//printk("FD motor on\n");
outb(FD_DOR, 0x1C);
called=0;
while(!called);
delay(DL);
return;
}
void fd_reset()
{
outb(FD_DOR, 0);
outb(FD_DOR, 0x0C);
outb(FD_DCR, 0); //
fd_cmd(0x03);
fd_cmd(0xdf);
fd_cmd(0x02);
fd_recalib();
called=0;
while(!called);
return;
}
int fd_recalib()
{
//printk("FD recalib\n");
fd_cmd(FD_RECALIBRATE);
fd_cmd(0);
delay(DL);
}
void fd_status()
{
char * status[] = {
"floppy drive 0 in seek mode/busy",
"floppy drive 1 in seek mode/busy",
"floppy drive 2 in seek mode/busy",
"floppy drive 3 in seek mode/busy",
"FDC read or write command in progress",
"FDC is in non-DMA mode",
"I/O direction; 1 = FDC to CPU; 0 = CPU to FDC",
"data reg ready for I/O to/from CPU (request for master)"};
int st=inb(FD_STATUS);
int i;
for (i=0; i<8; i++)
{
if (st & (1 << i)) {
???printk("test %d == %x\n", i, 1<<i);
???printk("%s\n",status);
}
}
}
static int fd_wait()
{
int st, i;
for (i=0; i<10000; i++)
{
st=inb(FD_STATUS);
if (st == STATUS_READY) return st;
}
return -1;
}
static int fd_cmd(unsigned char cmd)
{
outb(FD_DATA, cmd);
}
int fd_seek(unsigned char trk)
{
//printk("FD seek\n");
fd_cmd(FD_SEEK);
fd_cmd(0);
fd_cmd(trk);
called=0;
while(!called);
}
void setDMA()
{
//printk("Setting DMA\n");
cli;
outb(0xa,0x6);
outb(0xc,0);
outb(0x4,0);
outb(0x4,0);
outb(0xc,0);
outb(0x5,0xFF);
outb(0x5,0x1);
outb(0xb,0x46);
outb(0x81,0x8);
outb(0xa,0x2);
outb(0xa,0x2);
sti;
}
int fd_read() //read test of linear sector 0
{
fdmotor_on();
//outb(0x3f7, 0); //
fd_seek(0);
//delay(DL);
setDMA();
fd_cmd(FD_READ);
fd_cmd(0);
fd_cmd(0);
fd_cmd(0);
fd_cmd(1);
fd_cmd(2);
fd_cmd(18);
fd_cmd(0x1B);
fd_cmd(0xFF);
called=0;
while (!called);
printk("ST0 %x \n",inb(FD_DATA));
printk("ST1 %x \n",inb(FD_DATA));
printk("ST2 %x \n",inb(FD_DATA));
printk("Cyl %x \n",inb(FD_DATA));
printk("Hd %x \n",inb(FD_DATA));
printk("Sct %x \n",inb(FD_DATA));
printk("NBS %x \n",inb(FD_DATA));
memcpy(0x80000, buffer, 512);
fdmotor_off();
}
void print_fd_buffer()
{
int i;
for (i=0;i<512; i++)
{
printk("%x ",buffer&0x000000FF);
}
}
I detected another problem :
when I read a sector using fd_read() under bochs or vmware, all register status are OK but the first byte in my buffer is 0 (it must be 0xe9) this is about emulators...
now when I run this on a real PC the status register 0 is 0x80 (invalid command) ???
Re:problem with my floppy driver in pmode
Code: Select all
{
//printk("FD motor on\n");
outb(FD_DOR, 0x1C);
called=0;
while(!called);
delay(DL);
return;
}
You don't read the status of the seek (think it does give one back).
I refuse to check the setdma function, make it readable, and double-check it
You might want to pass floppy.h too, can't see the defines now.
Also, try using [ code ] and [ / code ] (without spaces) for your code.
Re:problem with my floppy driver in pmode
floppy.h is the same as "include\linux\fdreg.h"
the dma code works well, since it can read mem when working under an emulator, and the motor on returns an fd call ...
i d'ont see where is the problem
the dma code works well, since it can read mem when working under an emulator, and the motor on returns an fd call ...
i d'ont see where is the problem
Re:problem with my floppy driver in pmode
I have a pretty functional floppy driver in pmode code inside SOLAR OS...
In the FDD Test Application you can see all as it happening...
BTW 0x80 is waiting for a command on FDC8272
if i recall corectly
In the FDD Test Application you can see all as it happening...
BTW 0x80 is waiting for a command on FDC8272
if i recall corectly
Re:problem with my floppy driver in pmode
hoo, i m too stupid.... i foun the mistake in my code.
i doesn't work cause send the read command i don't wait for data , so I coppy the content of memory to my buffer before data transfer
i doesn't work cause send the read command i don't wait for data , so I coppy the content of memory to my buffer before data transfer
Code: Select all
int fd_read()? //read test of linear sector 0
{
? fdmotor_on();
? //outb(0x3f7, 0);? ? //
?
? fd_seek(0);
? //delay(DL);
? setDMA();
? fd_cmd(FD_READ);
? fd_cmd(0);
? fd_cmd(0);
? fd_cmd(0);
? fd_cmd(1);
? fd_cmd(2);
? fd_cmd(18);
? fd_cmd(0x1B);
? fd_cmd(0xFF);
? called=0;
? while (!called);
/* this is the fix for the code */
/* the function do a loop while data are not read */
fd_wait_data();
/*************************************/
? printk("ST0 %x \n",inb(FD_DATA));
? printk("ST1 %x \n",inb(FD_DATA));
? printk("ST2 %x \n",inb(FD_DATA));
? printk("Cyl %x \n",inb(FD_DATA));
? printk("Hd? %x \n",inb(FD_DATA));
? printk("Sct %x \n",inb(FD_DATA));
? printk("NBS %x \n",inb(FD_DATA));
? memcpy(0x80000, buffer, 512);
? fdmotor_off();
}