problem with my floppy driver in pmode

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
aladdin

problem with my floppy driver in pmode

Post by aladdin »

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 ???
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:problem with my floppy driver in pmode

Post by Candy »

is the variable volatile?
aladdin

Re:problem with my floppy driver in pmode

Post by aladdin »

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.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:problem with my floppy driver in pmode

Post by Candy »

We can help you better if we can see the code.
User avatar
Pype.Clicker
Member
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

Post by Pype.Clicker »

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

Code: Select all

static int flag;
void isr_handler() { flag = 1; }
void some_code() {
    flag=0;
    prepare_hardware();
    while(!flag);
    get_results();
}
the compiler can detect that 'flag' isn't touched by the body of the loop and thus optimize it as

Code: Select all

void some_code'() {
    flag = 0;
    ...
    if (!flag) while(1);
    get_result();
}
which will obviously be wrong.

Code: Select all

volatile int flag;
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).
aladdin

Re:problem with my floppy driver in pmode

Post by aladdin »

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) ???
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:problem with my floppy driver in pmode

Post by Candy »

Code: Select all

{
  //printk("FD motor on\n");
  outb(FD_DOR, 0x1C);
  called=0;
  while(!called);
  delay(DL);

  return;
}
Afaik, it shouldn't give an interrupt after turning the motor on.


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.
aladdin

Re:problem with my floppy driver in pmode

Post by aladdin »

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
bogdanontanu

Re:problem with my floppy driver in pmode

Post by bogdanontanu »

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
aladdin

Re:problem with my floppy driver in pmode

Post by aladdin »

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

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();


}

Post Reply