Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Алгоритм чтения сектора с дискеты в PM

36K
02 января 2013 года
kailot2
83 / / 15.12.2012
Всем доброго времени суток!!! Кто-нить кому не оч лень накидайте пожалуйста алгоритмик чтения сектора с дискеты в защищенном режиме. На уровне
В портик такой-то кидаем то то
Ждем столько-то
забираем из портика такого-то.
А то я чего то разобраться не могу. =(
360
02 января 2013 года
P*t*
474 / / 15.02.2007
Теория тут: http://www.cyberguru.ru/programming/assembler/assembler-programming-drives-page27.html

Напиши, кстати, что с предыдущем вопросом получилось.

Моя реализация:
Код:
long floppyTypes;
long floppyTimeToTurnOff[2];
long floppyTimeToWork[2];
long floppyIsRotated[2];
long floppyState[2];   // 0 - stop    1 - wait    2  - run
char p0x3f2;
void updateFloppies() {
    long a=0;
    for (a=0;a<2;a++) {
        if ((floppyState[a]==0) && (floppyIsRotated[a]==1)) {
            if ((--floppyTimeToTurnOff[a]) < 0) {
                p0x3f2 &= ~(1<<(a+4));
                out(0x3f2, p0x3f2);
                floppyIsRotated[a] = 0;
                floppyTimeToTurnOff[a] = 40;
                floppyTimeToWork[a] = 20;
            }
        }
        if (floppyState[a]==1) {
            if (!floppyIsRotated[a]) {
                p0x3f2 |= 1<<(a+4);
                out(0x3f2, p0x3f2);
                floppyTimeToTurnOff[a] = 40;
            }
            if (floppyTimeToWork[a]>0) floppyTimeToWork[a]--;
        }
    }
}

long floppyInterruptHappened;
void floppyInterruptHandler() {
    floppyInterruptHappened = 1;
    out(0x20, 0x20);
}

void floppyWait(long a) {
    while (floppyState[a]!=0);
    floppyState[a] = 1;
    while (floppyTimeToWork[a]>0);
    while (floppyState[1-a]==2);
    floppyState[a] = 2;
    p0x3f2 = (p0x3f2 & (~3)) | a;
    out(0x3f2, p0x3f2);
}

long floppyFind(long a, long cylinder, long head) {
    floppyInterruptHappened = 0;
    if ((in(0x3f4)&0x40) != 0) return -6;
    while ((in(0x3f4)&0x80) == 0);
    out(0x3f5, 0xf);
    while ((in(0x3f4)&0x80) == 0);
    out(0x3f5, head==0?a:a|4);
    while ((in(0x3f4)&0x80) == 0);
   
    out(0x3f5, cylinder);
    while (floppyInterruptHappened == 0);
    if ((in(0x3f4)&0x40) != 0) return -6;
    while ((in(0x3f4)&0x80) == 0);
    out(0x3f5, 0x8);
    while ((in(0x3f4)&0x40) == 0);
    while ((in(0x3f4)&0x80) == 0);
    long st0 = in(0x3f5);
    while ((in(0x3f4)&0x80) == 0);
    long pc = in(0x3f5);
    if (((8+16+64+128)&st0)!=0) return -6;
    if (pc!=cylinder) return -6;
    return 0;
}

long floppyReadWrite9kb(long a, long cylinder, long head, long write) {
    sti();
    floppyWait(a);
    long res = floppyFind(a, cylinder, head);

    if (res<0) return res;
    if ((in(0x3f4)&0x40) != 0) {
        floppyState[a] = 0;
        return -6;
    }
           
    if (write==0) {
        out(0xb, 0x46);
        out(0xc, 0x46);
    } else {
        out(0xb, 0x4a);
        out(0xc, 0x4a);
    }

    out(0x5, 0);
    out(0x5, 36);
    out(0x4, 0);
    out(0x4, 0);
    out(0x81, 5);
    out(0xa, 2);
    floppyInterruptHappened = 0;
    while ((in(0x3f4)&0x80) == 0);
    out(0x3f5, write==0?0x66:0x45);
    while ((in(0x3f4)&0x80) == 0);
    out(0x3f5, head==0?a:a|4);
    while ((in(0x3f4)&0x80) == 0);
    out(0x3f5, cylinder);
    while ((in(0x3f4)&0x80) == 0);
    out(0x3f5, head);
    while ((in(0x3f4)&0x80) == 0);
    out(0x3f5, 1);
    while ((in(0x3f4)&0x80) == 0);
    out(0x3f5, 2);
    while ((in(0x3f4)&0x80) == 0);
    out(0x3f5, 18);
    while ((in(0x3f4)&0x80) == 0);
    out(0x3f5, 0x1a);
    while ((in(0x3f4)&0x80) == 0);
    out(0x3f5, 0xff);
    while (floppyInterruptHappened == 0);
    while ((in(0x3f4)&0x80) == 0);
    long st0 = in(0x3f5);
    while ((in(0x3f4)&0x80) == 0);
    long st1 = in(0x3f5);
    while ((in(0x3f4)&0x80) == 0);
    long st2 = in(0x3f5);
    while ((in(0x3f4)&0x80) == 0);
    long c = in(0x3f5);
    while ((in(0x3f4)&0x80) == 0);
    long h = in(0x3f5);
    while ((in(0x3f4)&0x80) == 0);
    long r = in(0x3f5);
    while ((in(0x3f4)&0x80) == 0);
    long n = in(0x3f5);
   
    floppyState[a] = 0;
    if (((8+16+64+128)&st0)!=0) return -6;
   
    return 0;
}

long initFloppy() {
    writeString("Floppy initialization...  ", 6);
    out(0x70, 0x10);
    floppyTypes = in(0x71);
    writeString("fda: ", 14);
    switch (floppyTypes>>4) {
    case 0 : writeString("NO", 14); break;
    case 1 : writeString("360kb", 14); break;
    case 2 : writeString("1.2mb", 14); break;
    case 3 : writeString("720kb", 14); break;
    case 4 : writeString("1.44mb", 14); break;
    }
    writeString("  fdb: ", 14);
    switch (floppyTypes&0xf) {
    case 0 : writeString("NO", 14); break;
    case 1 : writeString("360kb", 14); break;
    case 2 : writeString("1.2mb", 14); break;
    case 3 : writeString("720kb", 14); break;
    case 4 : writeString("1.44mb", 14); break;
    }
    floppyState[0] = 0;
    floppyState[1] = 0;
    floppyIsRotated[0] = 0;
    floppyIsRotated[1] = 0;
    floppyTimeToTurnOff[0] = 40;
    floppyTimeToTurnOff[1] = 40;
    floppyTimeToWork[0] = 20;
    floppyTimeToWork[1] = 20;
    p0x3f2 = 0x0c;
    if (bootDisk<2) {
        p0x3f2 |= 1<<(bootDisk+4);
        floppyIsRotated[bootDisk] = 1;
        floppyTimeToWork[bootDisk] = 0;
    }
    writeString(" OK.\n", 2);
}

long floppyWrite(long descriptor, char* data, long size) {
    unsigned long fsize = *(unsigned long*)(0x30000 + descriptor*0x40 + 0x8);
    unsigned long nowPos = *(unsigned long*)(0x30000 + descriptor*0x40 + 0xc);
    long floppy = *(unsigned char*)(0x30000 + descriptor*0x40 + 0x4);
    if (nowPos+size>fsize) size = fsize-nowPos;
    long ans = size;
    while (size>0) {
        long cyl = (nowPos/(512*18))/2;
        long head = (nowPos/(512*18))%2;
        long res = floppyReadWrite9kb(floppy, cyl, head, 0);
        if (res<0) return res;
        long pos = nowPos%(512*18);
        long a;
        for (a=pos;a<min(pos+size, 512*18);a++)
            *(char*)(0x40000+a) = *(data++);
        res = floppyReadWrite9kb(floppy, cyl, head, 1);
        if (res<0) return res;
        nowPos += min(size, 512*18-pos);
        size -= min(size, 512*18-pos);
    }
    *(unsigned long*)(0x30000 + descriptor*0x40 + 0xc) = nowPos;
    return ans;
}

long floppyRead(long descriptor, char* data, long size) {
    unsigned long fsize = *(unsigned long*)(0x30000 + descriptor*0x40 + 0x8);
    unsigned long nowPos = *(unsigned long*)(0x30000 + descriptor*0x40 + 0xc);
    long floppy = *(unsigned char*)(0x30000 + descriptor*0x40 + 0x4);
    if (nowPos+size>fsize) size = fsize-nowPos;
    long ans = size;

    while (size>0) {
        long cyl = (nowPos/(512*18))/2;
        long head = (nowPos/(512*18))%2;
        long res = floppyReadWrite9kb(floppy, cyl, head, 0);
        if (res<0) return res;
        long pos = nowPos%(512*18);
        long a;
        for (a=pos;a<min(pos+size, 512*18);a++)
            *(data++) = *(char*)(0x40000+a);
        nowPos += min(size, 512*18-pos);
        size -= min(size, 512*18-pos);
    }
    *(unsigned long*)(0x30000 + descriptor*0x40 + 0xc) = nowPos;

    return ans;
}

long floppyReadLine(long descriptor, char* data, long size) {
    unsigned long fsize = *(unsigned long*)(0x30000 + descriptor*0x40 + 0x8);
    unsigned long nowPos = *(unsigned long*)(0x30000 + descriptor*0x40 + 0xc);
    long floppy = *(unsigned char*)(0x30000 + descriptor*0x40 + 0x4);
    if (nowPos+size>fsize) size = fsize-nowPos;
    long ans = 0;
    size--;
    while (size>0) {
        long cyl = (nowPos/(512*18))/2;
        long head = (nowPos/(512*18))%2;
        long res = floppyReadWrite9kb(floppy, cyl, head, 0);
        if (res<0) return res;
        long pos = nowPos%(512*18);
        long a;
        for (a=pos;a<min(pos+size, 512*18);a++) {
            *(data++) = *(char*)(0x40000+a);
            nowPos+=1;
            ans++;
            if (*(char*)(0x40000+a) == '\n') {
                *(unsigned long*)(0x30000 + descriptor*0x40 + 0xc) = nowPos;
                *(--data) = 0;
                return ans;
            }
        }
        size -= min(size, 512*18-pos);
    }
    *(unsigned long*)(0x30000 + descriptor*0x40 + 0xc) = nowPos;
    *data = 0;
    return ans;
}

long floppySetPosition(long descriptor, long mode, long value) {
    unsigned long size = *(unsigned long*)(0x30000 + descriptor*0x40 + 0x8);
    if (mode == 0) {
        if (value>size) value = size;
        if (value<0) value = 0;
        *(unsigned long*)(0x30000 + descriptor*0x40 + 0xc) = value;
    }
    if (mode == 1) {
        value = *(unsigned long*)(0x30000 + descriptor*0x40 + 0xc) + (long)value;
        if (value>size) value = size;
        if (value<0) value = 0;
        *(unsigned long*)(0x30000 + descriptor*0x40 + 0xc) = value;
    }
    if (mode == 2) {
        value = size - value;
        if (value>size) value = size;
        if (value<0) value = 0;
        *(unsigned long*)(0x30000 + descriptor*0x40 + 0xc) = value;
    }
    return 0;
}
36K
02 января 2013 года
kailot2
83 / / 15.12.2012
Цитата: P*t*

Напиши, кстати, что с предыдущем вопросом получилось.
[/code]


Да чего то не решилсо я переходить на си.Как то роднее мне мнемоники ассемблера чем сишные кракозябры. Все просто. Может позже, когда организую нормальную страничную адресацию, перейду.

36K
02 января 2013 года
kailot2
83 / / 15.12.2012
P*t* Я как понял ты тоже ОС писал\пишешь? Как успехи?
36K
02 января 2013 года
kailot2
83 / / 15.12.2012
А, вопрос как раз по предыдущему вопросу =)
Вот например написал я программулинку на сях.
Как ее компильнуть и слинковать в бинарь, и как указать линкеру адрес по которому я буду ее грузить?
Я вообще в Си и его компиляторах разбираюсь как в танках =)
Юзаю Dev-C++ под виндами. Может чего другого скачать?
360
03 января 2013 года
P*t*
474 / / 15.02.2007
Цитата: kailot2
P*t* Я как понял ты тоже ОС писал\пишешь? Как успехи?



Я писал, когда учился в десятом классе. Защищенный режим, многозадачность, виртуальная память и файловая система на дискете. Потом постепенно забросил, когда посмотрел исходный код minix и увидел, насколько он лучше написан.

Цитата: kailot2
А, вопрос как раз по предыдущему вопросу =)
Вот например написал я программулинку на сях.
Как ее компильнуть и слинковать в бинарь, и как указать линкеру адрес по которому я буду ее грузить?
Я вообще в Си и его компиляторах разбираюсь как в танках =)
Юзаю Dev-C++ под виндами. Может чего другого скачать?



Про винду ничего не скажу, я все делал под линуксом с компилятором gcc и линковщиком ld.
При компиляции и линковке надо указать в опциях
1) не подключать стандартные библиотеки
2) использовать архитектуру i386 (иначе на современных компьютерах скомпилится код для x86_64 и требуемым образом работать не будет)
3) выбрать формат бинарника. Для ld можно задать произвольное расположение файлов и секций: http://www.math.utah.edu/docs/info/ld_3.html
Все конкретные опции я в предыдущей теме писал.

36K
03 января 2013 года
kailot2
83 / / 15.12.2012
Гы =) я тоже в десятом классе.
36K
03 января 2013 года
kailot2
83 / / 15.12.2012
P*t* , Чет я не раскурил исходник твой. Вот объясни популярно, у меня есть процедурки чтения\записи в регистр данных, запуска мотора с ожиданием, поиска дорожки, и т.д. В каком порядке мне эти действия выполнять что бы например прочитать boot сектор дискетки?
360
03 января 2013 года
P*t*
474 / / 15.02.2007
void updateFloppies() - регулярно запускается по таймеру. Нужна чтобы выключать мотор дисковода, если уже долго не было обращений

void floppyInterruptHandler() - должно вызываться прерыванием floppy дисковода после окончания каждой операции. IRQ6. Настраивается в IDT

void floppyWait(long a) - включить и ждать, пока мотор разгонится до нужной скорости. "а" - это номер дисковода (0/1)

long floppyFind(long a, long cylinder, long head) - поиск нужной дорожки

long floppyReadWrite9kb(long a, long cylinder, long head, long write) - чтение, либо запись 9-и килобайт (одна дорожка целиком). Для данных используется буффер по фиксированному адресу. Этот адрес задается строками
 
Код:
out(0x4, 0);
out(0x4, 0); // младшие биты
out(0x81, 5); // старшие биты
Это описывается в моей ссылке на теорию на 28-ой и 29-ой страницах.

long initFloppy() - определение имеющихся дисководов при загрузке системы

Последующие функции можно не смотреть - они все работают через эти.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог