Page 1 of 1
Some floppy problems
Posted: Wed Apr 09, 2003 11:24 am
by Rootdown
Hello,
I've updated the therx floppy driver to my os. The problem comes when i want to read bootsector from a fat12 FD. Don't read well.
My struct for boot record is the same used by therx,
Code: Select all
typedef struct
{
char jump[3];
char oem_id[8];
short bps;
char spc;
short num_reserved;
char num_fats;
short num_rootents;
short total_sectors;
char media_ID_byte;
short spf;
short spt;
short heads;
short hidden_sectors;
short total_sectors_large;
short logical_drive_number;
char extended_signature;
long serial_number;
char volume_name[11];
char boot_code[456];
char magic[2];
} __attribute__ ((packed)) bootsector_t;
My problems comes int this line: read_block(0, 1, &fat_fd0);
( I try to read only the boot sector ). I've proved many diferents call at the read_bock function. when i try to printf on screen the magic pos 0 and pos 1 ( boot sector mark ), i get 160 ( using %d ).
I atach my floppy.h file. I don't really know how to fix or what is happening. I'm not asking you to fix my error, i want to learn why i meka i mistake.
Thanks.
Re:Some floppy problems
Posted: Wed Apr 09, 2003 11:37 am
by _mark
By my calculation, you are missing 4 bytes somewhere.
_mark()
Re:Some floppy problems
Posted: Wed Apr 09, 2003 3:42 pm
by Rootdown
Yes,
i only have 508 bytes on the struct. But if i use an array of 512 pos and char, when I read 511-510 i don't get the boot signature, and when try to read the oem info, i get some weird characters on screen.
Thanks for answering mark.
Re:Some floppy problems
Posted: Wed Apr 09, 2003 10:31 pm
by _mark
It is kind of hard to help without the code. But it has to be one of three things, either read_block is not doing what you think, what is on the disk is not what you think, or everything is fine and there is something wrong with your printf. If your sure of your read_block routine, copy the boot sector to a file and look at it in a hex editor to see what is really there. Also verify your printf function is correctly printing numbers.
Post the code if you want me or someone else to take a look.
_mark()
Re:Some floppy problems
Posted: Thu Apr 10, 2003 11:26 am
by roquefeler
I can't atach it, i recieve an error:
2: Unable to create '/home3/mega-tokyo/www/forum/attachments/uploaded_files/rfdos.txt': Permission denied
(/home3/www/mega-tokyo/forum/Sources/Post.php ln 697)
Re:Some floppy problems
Posted: Thu Apr 10, 2003 4:52 pm
by roquefeler
As i can't post the file,
I show you my funcition:
Code: Select all
boolean write_block(dword lba, dword num_sectors, char* buffer)
{
return floppy_rw(lba, num_sectors, buffer, FALSE);
}
// funcion real para leer o escribir segun bool read
boolean floppy_rw(dword lba, dword num_sectors, byte* buffer, boolean read)
{
int head,track,sector,tries, copycount = 0;
byte* p_tbaddr = (byte*)FLOPPY_DMA_PHYSICAL_ADDRESS;
byte* p_blockbuff = buffer;
// convert logical address into physical address
block2hts(lba, &head, &track, §or);
motoron();
if (!read && buffer)
{
for(copycount=0; copycount< (num_sectors*512); copycount++)
{
*p_tbaddr = *p_blockbuff;
p_blockbuff++;
p_tbaddr++;
}
}
for (tries = 0; tries < 3; tries++)
{
if (inportb(FDC_DIR) & 0x80)
{
fd_stat[0].dc = TRUE;
seek(1); // Borra el estado
recalibra();
motoroff();
return floppy_rw(lba, num_sectors, buffer, read);
}
if (!seek(track))
{
motoroff();
return FALSE;
}
outportb(FDC_CCR,0);
if (read)
{
dma_setup(floppy_tbaddr, FALSE,num_sectors*512 );
sendbyte(CMD_READ);
}
else
{
dma_setup(floppy_tbaddr, TRUE,num_sectors*512 );
sendbyte(CMD_WRITE);
}
sendbyte(head << 2);
sendbyte(track);
sendbyte(head);
sendbyte(sector);
sendbyte(2);
sendbyte(geometry.spt);
if (geometry.spt == DG144_SPT)
{
sendbyte(DG144_GAP3RW);
}
else
{
sendbyte(DG168_GAP3RW);
}
sendbyte(0xff);
// Espera a q se complete el comando
if (!fdwait(TRUE))
{
reset();
return floppy_rw(lba, num_sectors, buffer, read);
}
if ((fd_stat[0].buf[0] & 0xc0) == 0)
{
// si funciono, fuera de aqui.
break;
}
recalibra();
}
// Para el motor
motoroff();
if (read && buffer)
{
p_blockbuff = buffer;
p_tbaddr = (byte*)FLOPPY_DMA_PHYSICAL_ADDRESS;
for(copycount=0; copycount< (num_sectors*512); copycount++)
{
*p_blockbuff = *p_tbaddr;
p_blockbuff++;
p_tbaddr++;
}
}
return (tries != 3);
}
/*
FLOPPY_DMA_PHYSICAL_ADDRESS = 0x80000-65280 ( is a define )
And the str i use for control de FD:
Code: Select all
typedef struct fd_disk{
//char *label;
//unsigned short cyls;
unsigned short heads;
unsigned short tracks;
unsigned short spt;
}fd_disk;
typedef struct FD_ctrl{
boolean fdcok;
boolean motor_st;
char *name;
char type;
boolean dc;
unsigned char GAP3;
unsigned char DR;
fd_disk *disk;
int fdstop;
int tout;
int cbuf;
byte buf[7];
byte sr0;
byte track;
}FD_ctrl;
Don't know if you need something more.
Re:Some floppy problems
Posted: Fri Apr 11, 2003 10:46 am
by eL JeDi
Hi,
if you want send me your file my mail, and i try to post it and fix it. I'm not an expert, but i will do what i can

Re:Some floppy problems
Posted: Fri Apr 11, 2003 12:14 pm
by eL JeDi
I can't post the file. I get the same error. Try to post the code by parts
Re:Some floppy problems
Posted: Sat Apr 12, 2003 4:50 am
by roquefeler
/* this turns the motor on */
void motoron(void)
{
if (!fd_stat[0].motor_st) {
fd_stat[0].fdstop=-1; /* stop motor kill countdown */
outportb(FDC_DOR,0x1c);
delay(500); /* delay 500ms for motor to spin up */
fd_stat[0].motor_st = TRUE;
}
}
//////////////////////////////////////////////////////////////////////////////////////
/* this turns the motor off */
void motoroff(void)
{
if (fd_stat[0].motor_st) {
fd_stat[0].fdstop=36; /* start motor kill countdown: 36 ticks ~ 2s */
}
}
//////////////////////////////////////////////////////////////////////////////////////
void fdc_st_ini()
{
int n;
for (n=0;n<NUMFDS;n++)
{
fd_stat[n].fdcok=0;
fd_stat[n].motor_st=0;
fd_stat[n].type=0;
fd_stat[n].dc=0;
fd_stat[n].GAP3=0;
fd_stat[n].DR=0;
fd_stat[n].disk=NULL;
fd_stat[n].fdstop=0;
fd_stat[n].tout=0;
fd_stat[n].sr0=0;
fd_stat[n].track=0xff;
}
}
//////////////////////////////////////////////////////////////////////////////////////
/* sendbyte() routine from intel manual */
void sendbyte(int byte)
{
volatile int msr;
int tmo;
for (tmo = 0;tmo < 128;tmo++) {
msr = inportb(FDC_MSR);
if ((msr & 0xc0) == 0x80) {
outportb(FDC_DATA,byte);
return;
}
inportb(0x80); /* delay */
}
}
//////////////////////////////////////////////////////////////////////////////////////
/* getbyte() routine from intel manual */
int getbyte()
{
volatile int msr;
int tmo;
for (tmo = 0;tmo < 128;tmo++) {
msr = inportb(FDC_MSR);
if ((msr & 0xd0) == 0xd0) {
return inportb(FDC_DATA);
}
inportb(0x80); /* delay */
}
return -1; /* read timeout */
}
//////////////////////////////////////////////////////////////////////////////////////
int detect_fd()
{
char a,b,c;
unsigned char gs[]= {27,42,42,27,27,27};
// selecionamos en la BIOS el byte q indica el tipo de Unidad
outportb(0x70, 0x10);
a = inportb(0x71);
b=a>>4;
c=a & 0x0F;
fd_stat[0].type=b;
fd_stat[0].name="fda";
fd_stat[0].GAP3=gs;
fd_stat[1].type=c;
fd_stat[1].name="fdb";
fd_stat[1].GAP3=gs[c];
}
//////////////////////////////////////////////////////////////////////////////////////
void fdc()
{
fd_stat[1].fdcok=TRUE;
fd_stat[2].fdcok=TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////
boolean fdwait(boolean estao)
{
// Timeout = 1seg
fd_stat[0].tout=1000;
while ( !(fd_stat[0].fdcok) && fd_stat[0].tout);
fd_stat[0].cbuf=0;
while ((inportb(FDC_MSR) & (1<<4)) && (fd_stat[0].cbuf < 7))
{
fd_stat[0].buf[fd_stat[0].cbuf] = getbyte();
fd_stat[0].cbuf++;
}
if (estao)
{
// Mana SENSEI al controlador de la Disquetera.
sendbyte(CMD_SENSEI);
fd_stat[0].sr0 = getbyte();
fd_stat[0].track = getbyte();
}
fd_stat[0].fdcok = FALSE;
if (!fd_stat[0].tout)
{
// time out
if (inportb(FDC_DIR) & 0x80)
{
fd_stat[0].dc = TRUE;
}
return FALSE;
}else{
return TRUE;
}
}
//////////////////////////////////////////////////////////////////////////////////////
boolean seek(int trk)
{
// Comprobamos si ya estamos en la posicion trk
if (fd_stat[0].track == trk) { return TRUE; } // si ya estamos posicionados, devuelve TRUE
motoron();
// Mandamos comando al controlador.
sendbyte(CMD_SEEK);
sendbyte(0);
sendbyte(trk);
// ESperamos a que acabe la disquetera
if (!fdwait(TRUE)) { return FALSE; } // Devuelve FALSE si TIMED OUT
/* now let head settle for 15ms */
delay(15);
motoroff();
/* check that seek worked */
if ((fd_stat[0].track != trk)||(fd_stat[0].sr0 != 0x20)) { return FALSE; }
else { return TRUE; }
}
Re:Some floppy problems
Posted: Sat Apr 12, 2003 4:53 am
by roquefeler
void recalibra()
{
// Ponemos en marcha el motor de la disquetera
motoron();
// Envia comando al controlador
sendbyte(CMD_RECAL);
sendbyte(0);
// Esperar a que finalice el comando.
fdwait(TRUE);
// Apagar el motor
motoroff();
}
//////////////////////////////////////////////////////////////////////////////////////
void reset(void)
{
// Para el motor y desactiva IRQ/DMA
outportb(FDC_DOR,0);
fd_stat[0].fdstop=0;
fd_stat[0].motor_st = FALSE;
// data rate= 500K/s
outportb(FDC_DRS,0);
// Rehabilita IRQs
outportb(FDC_DOR,0x0c);
fd_stat[0].fdcok = TRUE;
fdwait(TRUE);
// Tiempos para la disquetera, los saca de la BIOS
sendbyte(CMD_SPECIFY);
sendbyte(0xdf); /* SRT = 3ms, HUT = 240ms */
sendbyte(0x02); /* HLT = 16ms, ND = 0 */
// Borra el estado de cambio de disco
seek(1);
recalibra();
// Cambio de disco = falso
fd_stat[0].dc = FALSE;
}
//////////////////////////////////////////////////////////////////////////////////////
void fdc_ini()
{
// Instalamos el Handle del Floppy
set_idt_entry((unsigned long)&irq6, 0x26);
EnableIRQ(6);
// Handle del timerpara apagar el floppy
//set_idt_entry((unsigned long)&timer0, 0x20);
//EnableIRQ(6);
//Inicializamos la estructura de contrl del floppy.
fdc_st_ini(fd_stat);
//Detectando Unidades:
detect_fd(fd_stat);
printf("Unidades de Disco:\n");
printf("Unidad A: %s \n",fd_type[fd_stat[0].type]);
printf("Unidad B: %s \n",fd_type[fd_stat[1].type]);
motoron();
motoroff();
}
// Convierte direccion lineal en formato pista, cilindro...
void block2hts(int block,int *head,int *track,int *sector)
{
*head = (block % (geometry.spt * geometry.heads)) / (geometry.spt);
*track = block / (geometry.spt * geometry.heads);
*sector = block % geometry.spt + 1;
}
////////////////////////////////////////////////////////////
// read block (blockbuff is 512 byte buffer)
boolean read_block(dword lba, dword num_sectors, char* buffer)
{
int track=0, sector=0, head=0, track2=0, result=0, loop=0;
// The FDC can read multiple sides at once but not multiple tracks
block2hts(lba, &head, &track, §or);
block2hts(lba+num_sectors, &head, &track2, §or);
if (track!=track2)
{
for(loop=0; loop < num_sectors; loop++)
{
result = floppy_rw(lba+loop, 1, buffer+(loop*512), TRUE);
}
return result;
}
return floppy_rw(lba, num_sectors, buffer, TRUE);
}
/*
void read_block(int block,unsigned char *blockbuff, int size)
{
printf("Floppy");
log_disk(0);
block = (int)(block / 512);
fdc_rw(block,blockbuff,TRUE);
}*/
////////////////////////////////////////////////////////////
// write block (blockbuff is 512 byte buffer) */
boolean write_block(dword lba, dword num_sectors, char* buffer)
{
return floppy_rw(lba, num_sectors, buffer, FALSE);
}
Re:Some floppy problems
Posted: Sat Apr 12, 2003 4:55 am
by roquefeler
Code: Select all
boolean floppy_rw(dword lba, dword num_sectors, byte* buffer, boolean read)
{
int head,track,sector,tries, copycount = 0;
byte* p_tbaddr = (byte*)FLOPPY_DMA_PHYSICAL_ADDRESS;
byte* p_blockbuff = buffer;
// convert logical address into physical address
block2hts(lba, &head, &track, §or);
// enciende el motor de la disquetera
motoron();
if (!read && buffer)
{
// Copia datos del buffer al buffer de la disquetera
for(copycount=0; copycount< (num_sectors*512); copycount++)
{
*p_tbaddr = *p_blockbuff;
p_blockbuff++;
p_tbaddr++;
}
}
for (tries = 0; tries < 3; tries++)
{
// cambio de disco??
if (inportb(FDC_DIR) & 0x80)
{
fd_stat[0].dc = TRUE;
seek(1); // Borra el estado
recalibra();
motoroff();
return floppy_rw(lba, num_sectors, buffer, read);
}
// Posiciona el cabezal
if (!seek(track))
{
motoroff();
return FALSE;
}
// data rate =500K/s
outportb(FDC_CCR,0);
// Envia se?al al controlador DMA
if (read)
{
//dma_xfer(2, floppy_tbaddr, num_sectors*512, FALSE);
dma_setup(floppy_tbaddr, FALSE,num_sectors*512 );
sendbyte(CMD_READ);
}
else
{
dma_setup(floppy_tbaddr, TRUE,num_sectors*512 );
//dma_xfer(2, floppy_tbaddr, num_sectors*512, TRUE);
sendbyte(CMD_WRITE);
}
sendbyte(head << 2);
sendbyte(track);
sendbyte(head);
sendbyte(sector);
sendbyte(2); // 512 bytes/sector
sendbyte(geometry.spt);
if (geometry.spt == DG144_SPT)
{
sendbyte(DG144_GAP3RW); // gap 3 para 1.44M read/write
}
else
{
sendbyte(DG168_GAP3RW); // gap 3 para 1.68M read/write
}
sendbyte(0xff); // DTL
// Espera a q se complete el comando
if (!fdwait(TRUE))
{
reset();
return floppy_rw(lba, num_sectors, buffer, read);
}
if ((fd_stat[0].buf[0] & 0xc0) == 0)
{
// si funciono, fuera de aqui.
break;
}
recalibra(); // si no, vuelva a intertarlo cu?aaao
}
// Para el motor
motoroff();
if (read && buffer)
{
// Mete datos dentro del buffer.
p_blockbuff = buffer;
p_tbaddr = (byte*)FLOPPY_DMA_PHYSICAL_ADDRESS;
for(copycount=0; copycount< (num_sectors*512); copycount++)
{
*p_blockbuff = *p_tbaddr;
p_blockbuff++;
p_tbaddr++;
}
}
return (tries != 3);
}
And my DMA SETUP FUNCTION:
Code: Select all
void dma_setup(long address, char mode, int size)
{
asm("cli");
outportb(0x0A, 2 | 4); //Set channel Mask Bit
outportb(0x0C, 0); //Reset Flip-flop
if(mode == 1) //Memory to Device ( DEV_READ )
outportb(0x0B, 0x5A);
else //Device to Memory
outportb(0x0B, 0x56);
outportb(0x81, address >> 16); //Set Page
outportb(0x04,(address & 0xFFFF) & 0xFF); //Output Lo Byte of offset
outportb(0x04,(address & 0xFFFF) >> 8); //Output Hi Byte of offset
outportb(0x05,size & 0xff); //Output Lo Byte of length
outportb(0x05,size >> 8); //Output Hi Byte of length
outportb(0x0A, 2); //Clear Channel Mask
}
Thanks
Re:Some floppy problems
Posted: Tue Apr 15, 2003 10:37 am
by Roquefeler_
Please,
anyone can tell what i'm doing wrong?? Or why it doesn't works??
When i do a read_block() function, and i do a printf of the array i get the same output before and after.
Could it be my dam_setup function?? ( is the therx OS one)