User Tag List

Показано с 51 по 60 из 95

Тема: Как писать на HDD?

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1
    Nikolaj Amosov (2:5030/675.50)
    Гость

    По умолчанию Как писать на HDD?

    FromNet: St.Petersburg (fido.mariinsky.ru)


    Приветствую тебя, All!

    С грустью смотрю на уменьшающееся свободное место на своем HDD.
    Hа рабочем разделе iS-DOS осталось около 1 Мб. Есть другой HDD,
    большего размера, но с немного другой "геометрией" - у него 63
    сектора на каждую голову, а у старого диска 62 сектора. Из-за
    этого простое посекторное копирование MFS-раздела со старого
    диска на новый не даёт положительного результата.
    Решено было написать программу на Спектруме, которая скопирует
    информацию и сделает необходимую коррекцию относительных
    адресов начал разделов на диске. Саму коррекцию сделать не
    сложно. Гораздо сложнее оказалось скопировать диск. Программа
    периодически "подвисает" на опросе готовности принимающего
    диска. Причём каждый раз в разных местах, т.е. нет никакой
    закономерности, что при записи такого-то сектора винт уйдёт в
    себя.
    Пробовал по разному чередовать опросы BUSY и DRQ, но чего-то
    никак не получается. Обратил внимание, что чем больше секторов
    я пишу за один раз, тем дальше успеваю продвинуться. Если
    писать по одному сектору, то вероятность зависнуть в самом
    начале процесса довольно высока.

    Пишу вот таким кодом (место где зависаем отмечено ***):

    ========================== CLONEHDD.C ==========================

    ;Здесь чтение с MASTER

    [disk error]

    ;Здесь запись на SLAVE

    ;Позиционирование HDD SLAVE
    LD DE,(_SCIL) ;Hомер цилиндра
    LD HL,(_SSEC) ;Головка и номер сектора
    LD A,#B0 ;HDD SLAVE
    CALL WRITECHS ;Позиционирование

    CALL WAITNOBUSY
    ; CALL WAITDRDY

    ;Запись на HDD SLAVE
    LD A,NS ;Количество секторов для записи
    LD BC,regSECS ;В регистр количества секторов
    OUT (C),A

    LD A,#30
    CALL SENDCOMMAND

    ; CALL WAITNOBUSY

    ; CALL CHECKERROR
    ; JR C,ERRORCMD

    LD HL,BUFFER ;Адрес буфера
    DUP NS ;Сколько сектов пишем
    *** CALL WAITDRQ ;Ожидание готовности к приему данных
    CALL WRITE_1S ;Пишем один сектор
    ;*** CALL WAITNOBUSY
    EDUP

    CALL WAITNOBUSY

    CALL READCHS ;Читаем положение SLAVE
    LD BC,S_HEADS<8|S_SECTORS; это параметры геометрии SLAVE
    CALL SEC_PLUS1
    LD (_SSEC),HL ;Запоминаем HEAD&SECTOR
    LD (_SCIL),DE ;Запоминаем CILINDR

    JP LOOP; Hа чтение MASTER


    ;Расчет нового положения сектора после чтения/записи
    ;Вычисляет положение следующего сектора
    ;Hа входе:
    ;H=номер головки
    ;L=номер сектора
    ;DE=номер цилиндра
    ;B=количество головок на цилиндре
    ;C=количество секторов на головку
    ;Hа выходе:
    ;Все тоже самое, только пересчитанное
    SEC_PLUS1
    LD A,L ;Hомер сектора
    INC L ;Следующий сектор
    CP C ;Сравнили с максимально возможным
    RET C ;Hовый меньше максимального
    LD L,1 ;Иначе начинаем с первого сектора
    INC H ;Следующая голова
    LD A,H ;Hомер головки
    CP B ;Сравнили с максимально возможной
    RET C ;Только если меньше,т.к. головы с нуля
    LD H,0 ;Обнуляем номер головы
    INC DE ;И увеличиваем номер цилиндра
    RET


    ;----------------------------------------------
    ; HDD DRIVER v1.0 FOR SMUC WITH OPEN DOS PORTS
    ;----------------------------------------------
    regCOMM EQU #FFBE ;Регистр команд (запись)
    regSTAT EQU #FFBE ;Регистр состояния (чтение)
    regDEVC EQU #FEBE ;Регистр накопителя
    regCILH EQU #FDBE ;Регистр цилиндра старшая часть
    regCILL EQU #FCBE ;Регистр цилиндра младшая часть
    regNUMS EQU #FBBE ;Регистр номера сектора
    regSECS EQU #FABE ;Регистр счетчика секторов
    regERRR EQU #F9BE ;Регистр ошибки
    regDATL EQU #F8BE ;Регистр данных младшая часть
    regDATH EQU #D8BE ;Регистр данных старшая часть

    ;****************************************
    ;*** Ожидание освобождения устройства ***
    ;****************************************
    WAITNOBUSY
    LD BC,regSTAT
    IN A,(C)
    RLCA
    RET NC
    JR WAITNOBUSY

    ;******************************
    ;*** Чтение регистра ошибок ***
    ;******************************
    ;Hа выходе Flag C=1 Есть ошибки
    CHECKERROR
    LD BC,regERRR
    IN A,(C)
    RLCA
    RET

    ;*********************************************
    ;*** Ожидание готовности к передаче данных ***
    ;*********************************************
    WAITDRQ
    LD BC,regSTAT
    IN A,(C)
    BIT 3,A
    RET NZ
    JR WAITDRQ

    ;***************************************
    ;*** Ожидание готовности накопителя ****
    ;***************************************
    WAITDRDY
    LD BC,regSTAT
    IN A,(C)
    BIT 6,A
    RET NZ
    JR WAITDRDY

    ;****************************
    ;*** Передача команды HDD ***
    ;****************************
    SENDCOMMAND
    LD BC,regCOMM
    OUT (C),A
    RET

    ;********************************
    ;*** Позиционирование головок ***
    ;********************************
    ;Hа входе:
    ;A=#A0 MASTER / #B0 SLAVE
    ;DE=номер цилиндра
    ;H=номер головки
    ;L=номер сектора
    WRITECHS
    LD BC,regDEVC
    OR H
    OUT (C),A
    DEC B
    OUT (C),D
    DEC B
    OUT (C),E
    DEC B
    OUT (C),L
    RET


    ;********************************
    ;*** Чтение положения головки ***
    ;********************************
    ;Hа выходе:
    ;DE=номер цилиндра
    ;H=номер головки
    ;L=номер сектора
    READCHS
    LD BC,regDEVC
    IN A,(C)
    AND #0F
    LD H,A
    DEC B
    IN D,(C)
    DEC B
    IN E,(C)
    DEC B
    IN L,(C)
    RET


    ;**********************
    ;*** Чтение сектора ***
    ;**********************
    ;Hа входе:
    ;HL=адрес памяти куда читать
    ;Портит регистр DE
    _RN EQU #10; Степень раскрытия цикла чтения
    ;Чем меньше значение, тем быстрее работает чтение, но больше
    ;занимает памяти. Число должно быть из ряда:1,2,4,8,16...256
    READ_1S LD A,_RN

    LD DE,#D8F8
    READ_S DUP #100/_RN
    DD 43EDA242EDA2 ;LD B,E:INI:LD B,D:INI
    EDUP
    DEC A

    ; IF0 ($-READ_S); блин, как сделать эту проверку?
    ; JR NZ,READ_S
    ; ELSE
    JP NZ,READ_S
    ; ENDIF

    RET

    ;**********************
    ;*** Запись сектора ***
    ;**********************
    ;Hа входе:
    ;HL адрес памяти откуда писать
    ;Hа выходе:
    ;HL адрес следующей ячейки памяти
    ;Портит регистр DE
    _WN EQU #10; Степень раскрытия цикла записи
    WRITE_1S
    LD A,_WN

    LD DE,#D8F8
    LD (WRITESP),SP
    LD SP,HL
    WRITE_S DUP #100/_WN
    DD E142ED6143ED69; POP HL:B,D:OUT (C),H:B,E:OUT (C),L
    EDUP
    DEC A

    ; JR NZ,WRITE_S
    JP NZ,WRITE_S

    LD H,A
    LD L,A
    ADD HL,SP
    LD SP,#0000
    RET
    ================================================== ==============

    Подскажите правильную последовательность действий для записи на
    диск, т.е. протокол общения с HDD в режиме записи.

    откорректировать и не париться, но хочется разобраться в чём же
    дело. Да и до ближайшего оффтопика мне тащиться три остановки...

    [REAL ZX]

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Как писать простые програмы?
    от alexfreed в разделе Софт
    Ответов: 3
    Последнее: 11.12.2005, 14:57
  2. Ответов: 35
    Последнее: 25.11.2005, 01:46

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •