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.
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.
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.
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.
/* 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;
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; }
}
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();
// The FDC can read multiple sides at once but not multiple tracks
block2hts(lba, &head, &track, §or);
block2hts(lba+num_sectors, &head, &track2, §or);