Проблема с флопом
:confused: Люди добрые, помогите, если знаете. Пишу свою ОС. Загружаю boot-сектором ядро, в ядре перехожу в защищенный режим. Хочу сварганить работу с флопом с DMA, а он падла все не сбрасывает бит занятости в 0x3f4 порту. И recalibrate пытался выполнить, и сбросить бит reseta, все одно и тоже. Че за нафиг?
Просьба не сквернословить, это всё таки ФОРУМ:mad:
OK:
Люди добрые, помогите, если знаете. Пишу свою ОС. Загружаю boot-сектором ядро, в ядре перехожу в защищенный режим. Хочу сварганить работу с флопом с DMA, а этот нехороший человек все не сбрасывает бит занятости в 0x3f4 порту. И recalibrate пытался выполнить, и сбросить бит reseta, все одно и тоже. Че за неприятная ситуация?
В чём твоя ошибка, я не знаю, но предлагаю другой выход из ситуатции:
можно не парится с портами, можно пользоваться перерыванием BIOS
int 13h
Лично я при работе с диском всегда int 13h использую
[COLOR="Blue"]Здесь есть полное описание[/COLOR]
Люди добрые, помогите, если знаете. Пишу свою ОС. Загружаю boot-сектором ядро, в ядре перехожу в защищенный режим. Хочу сварганить работу с флопом с DMA, а этот нехороший человек все не сбрасывает бит занятости в 0x3f4 порту. И recalibrate пытался выполнить, и сбросить бит reseta, все одно и тоже. Че за неприятная ситуация?[/QUOTE]
Ты бы код показал. Тогда яснее станет что не так.
Pavia, поддерживаю. Я давно это хотел написать и еще то, что существует довольно много osdev-исходников, где можно посмотреть, как выполняется работа с флоппиком. На sysbin'е какое-то время назад мы тоже затрагивали подобные вопросы... Да их вообще периодически затрагивают в разных форумах по низкоуровневому программированию!
Ну и страшные же здесь смайлики :)
после загрузки прерываниями и перед переходом в защищенный режим выключаю мотор
mov dx, 0x3f2
xor al, al
out dx, al
после этого, уже в сишном коде у меня идут:
unsigned char fdc_interrupt_status = 0; //переменная, устанавливается в 1 обработчиком
прерываний от флоппи
unsigned char fdc_read_reg (void)
{
register unsigned char status;
do
{
status=inportb(0x3f4);
printf("status write: [0x%x]\n", status);
}while (status!=0xc0); //здесь не сбрасывается 4-й бит
return (inportb(0x3f5));
}
void fdc_write_reg (unsigned char value)
{
register unsigned char status;
do
{
status=inportb(0x3f4);
printf("status write: [0x%x]\n", status);
}while (status!=0x80); //и здесь не сбрасывается 4-й бит
outportb(0x3f5, value);
return;
}
__inline__ void fdc_floppy_on (void)
{
unsigned char reg = 0xc;
reg|=FDC_DRIVE;
#if FDC_DRIVE == 0
reg|=0x10;
#elif FDC_DRIVE == 1
reg|=0x20;
#endif
outportb(0x3f2, reg);
return;
}
__inline__ void fdc_floppy_off (void)
{
outportb(0x3f2, 0);
return;
}
void fdc_seek (unsigned char head, unsigned short cylinder)
{
unsigned char reg = 0;
fdc_interrupt_status=0;
reg|=FDC_DRIVE;
reg|=(head<<2);
fdc_write_reg(0xf);
fdc_write_reg(reg);
fdc_write_reg(cylinder);
delay(1);
return;
}
unsigned char fdc_seek_result (void)
{
unsigned char reg[2];
while (fdc_interrupt_status==0);
fdc_write_reg (0x8);
reg[0] = fdc_read_reg();
reg[1] = fdc_read_reg();
fdc_interrupt_status=0;
printf(" ST0: [0x%x]\n", reg[0]);
//printf(" PCN: [0x%x]\n", reg[1]);
return reg[1];
}
void fdc_program_dma (unsigned char dmamode, unsigned int dmamem, unsigned char dmasize)
{
union
{
unsigned char byte[4];
unsigned int adress;
} reg;
reg.adress=dmamem;
i_disable();
outportb (0xc, 0x0);
outportb (0xa, 0x6);
outportb (0xb, dmamode);
outportb (0xc, 0x0);
outportb (0x04, reg.byte[0]);
outportb (0x04, reg.byte[1]);
outportb (0x81, reg.byte[2]);
outportb (0xc, 0x0);
outportb (0x5, 0xff);
outportb (0x5, DMA_SIZE);
outportb (0xa, 0x2);
i_enable();
return;
}
unsigned int *fdc_read_sector (unsigned char head, unsigned short cylinder, unsigned short sector)
{
unsigned char result[7];
unsigned char reg = 0;
unsigned char i;
fdc_interrupt_status=0;
reg|=(head<<2);
reg|=FDC_DRIVE;
fdc_write_reg(0x66);
fdc_write_reg(reg);
fdc_write_reg(cylinder);
fdc_write_reg(head);
fdc_write_reg(sector);
fdc_write_reg(SECTOR_SIZE);
fdc_write_reg(EOT);
fdc_write_reg(GAP3);
fdc_write_reg(DTL);
while (fdc_interrupt_status==0);
result[0]=fdc_read_reg();
result[1]=fdc_read_reg();
result[2]=fdc_read_reg();
result[3]=fdc_read_reg();
result[4]=fdc_read_reg();
result[5]=fdc_read_reg();
result[6]=fdc_read_reg();
fdc_interrupt_status=0;
for (i=0; i<=6; i++)
printf ("\t[0x%x]\n", result);
return (int*)DMA_MEM;
}
void specify (void)
{
fdc_write_reg(0x3);
fdc_write_reg(0xf1);
fdc_write_reg(0xfe);
return;
}
void fdc_recalibrate (void)
{
unsigned char reg=FDC_DRIVE;
fdc_write_reg(0x7);
fdc_write_reg(reg);
return;
}
void fdc_reset (void)
{
outportb(0x3f2, 0x0);
outportb(0x3f2, 0x4);
return;
}
Все это великолепие я вызываю так:
fdc_reset();
specify();
fdc_recalibrate();
fdc_floppy_on();
delay(18); //примерно 1 секунда
do
{
fdc_seek(0, 0);
}while (fdc_seek_result()!=0);
fdc_program_dma (READ, DMA_MEM, DMA_SIZE);
outportb (0x3F7, 0);
fdc_read_sector (0, 0, 1);
fdc_floppy_off();
но ещё в самом начале, при команде specify комп зацикливается, т.к. получает от контроллера сигнал занятости.
Если у меня что не так сделано, объясните, пожалуйста.
А с int - так это мне вообще не подходит.
Попробуй в fdc_reset команду "outportb(0x3f2, 0x4);" заменить на "outportb(0x3f2, 0xC);"
Перед этим я бутсектором гружусь прерываниями, затем в защищенном режиме кидаю в 0x3f2 0 для отключения мотора. больше я ничего не делаю, а он все равно занят. Может мотор останавливаю нправильно?:confused:
У меня так же - самое первое отключение мотора - 0 в 3F2h, при этом все нормально работает! Попробуй поначалу не использовать команду задания режима работы (у тебя вроде бы она реализована в функции specify)...
А нельзя ли получить сорцы этой мега-оси? Я посмотреть хочу, если это конечно не коммерческая тайна. А то везде, где смотрел либо нет того, что нужно, либо как-то по левому, и неизвестно как работает.
Что касается моей оси, то я, возможно, и после первого официального релиза сам открывать исходники не буду, но некоторые из известных мне людей придерживаются совершенно других принципов (чем раньше откроешь - тем лучше), вот, например, из XSystem исходник, правда, его работоспособность я не гарантирую, потому как сам не проверял: