1 Отредактировано zpilot (08-05-2022 22:47)

Тема: Вопрос по контроллеру 840К

Всем добрых суток.
Прошу помощи с алогоритмом работы Агат <-> контроллер. Если я правильно понимаю, Агат обращаясь к ПЗУ контроллера запускает из нее "драйвер", который читает 0 сектор с 0 дорожки, затем передает управление по адресу 800, где лежат данные 0 сектора, которые, в свою очередь, читают остальные сектора 0 трека. Чтение происходит следующим образом. Сбрасываем синхробит по С0ХА, и ждем вновь его появления. Появился - начало сектора - читаем код А4 (по техническому описанию, мы его, по идее, прочитать не должны, тк в этот момент не выставлен бит "байт получен", но драйвер его все-таки читает, далее читаем код 95, 65, FE, трек, сектор, 5А. Если все верно, то ждем синхробита данных сектора, если нет, ждем сихробит заголовка сектора.
Но, алгоритм чтения 1 трека и последующих мне не понятен. Может кто прояснить, чем отличается чтение 0 трека от всех остальных?

Да, забыл написать, что вначале драйвер проверяет 0 трек или нет, если нет, двигает головку пока не появится бит 0 трека в регистре S.

2 Отредактировано Voldemar0 (09-05-2022 19:09)

Re: Вопрос по контроллеру 840К

> затем передает управление по адресу 800

$801
В $800 будет байт, указывающий количество секторов, которые драйвер должен был прочитать.
Обычно это 1, но возможны варианты.


> Чтение происходит следующим образом. Сбрасываем синхробит по С0ХА, и ждем вновь его появления.
> Появился - начало сектора - читаем код А4 (по техническому описанию, мы его, по идее, прочитать не
> должны, тк в этот момент не выставлен бит "байт получен",

Чтение байта и выставление флага "синхросбой" - это две параллельных операции.
Так что и байт будет и флаг готовности и синхросбой тоже.
Но смысл этого чтения состоит, в общем-то, в том, чтобы очистить как раз флаг готовности.
И уже следующий байт читать, будучи готовым именно к чтению байта, а не анализу флага синхросбоя.

/* Байтрейт у 840ки близок к пределу 6502 и ждать или синхро или байт может не получиться по тактам. */

Т.е. этот читаемый байт будет мусорным, и, скорее всего, это будет $FF.

/*
Строго говоря, я не знаю зачем нужен этот байт.
Есть вероятность, что ранние версии контроллера или предполагали неправильное чтение этого байта
или разработчики допускали, что это возможно (в возможных будущих версиях контроллера ?). Но анализ контроллера показал, что этот байт
вполне определённый и можно было бы сразу, получив синхро, забирать его из регистра.
Более того, есть прога Mouse Graph (графический редактор), в защите от копирования которого (от версий вроде 3.8 и выше) как раз используется такое вот чтение подряд. И это работает.
*/

> но драйвер его все-таки читает, далее читаем код 95, 65, FE, трек, сектор, 5А.

FE - номер тома, может быть и не FE. Зависит от фантазии того, кто создавал диск.
В общем-то, форматнуть диск номером тома отличным от fe довольно просто (в среде dos33 + Basic-60):

INIT HELLO, V121

Т.е. после V задаётся нужный номер (десятичный).
Думаю, в ИКП-шных бейсиках этот способ также сработает, в т.ч. с 840к-флопом.


> Но, алгоритм чтения 1 трека и последующих мне не понятен. Может кто прояснить, чем отличается чтение 0 трека от всех остальных?

Элементарно: на нулевом треке располагается полноценный драйвер, как только его прочитали, всё остальное (включая и хвост нулевого трека) читает уже он.
В совсем "бюджетном" варианте сами переводим голову на следующий трек и снова обращаемся к ROM-драйверу. Где-то вроде я такое однажды видел (игротека какая нибудь?), но так редко делали.

Код в ROM крайне облегчённый, он не умеет ни делать рекалибровку головы, ни двигать её (кроме как в нулевой трек), ни считать попытки чтения. Он не проверяет эпилоги полей (а без этого надёжность чтения поля адреса, не защищённого CRC, получается сомнительной). Да и интерфейс его вызова тоже слегка мозголомный и неудобный. Поэтому - чем раньше тем лучше - операционка пытается избежать его использования.

3 Отредактировано zpilot (09-05-2022 23:18)

Re: Вопрос по контроллеру 840К

Voldemar0 пишет:

> затем передает управление по адресу 800

$801
В $800 будет байт, указывающий количество секторов, которые драйвер должен был прочитать.
Обычно это 1, но возможны варианты.

Да, согласен, 801.


> Чтение происходит следующим образом. Сбрасываем синхробит по С0ХА, и ждем вновь его появления.
> Появился - начало сектора - читаем код А4 (по техническому описанию, мы его, по идее, прочитать не
> должны, тк в этот момент не выставлен бит "байт получен",

Voldemar0 пишет:

>Чтение байта и выставление флага "синхросбой" - это две параллельных операции.
Так что и байт будет и флаг готовности и синхросбой тоже.
Ото со стороны контроллер - дисковод, а я имел ввиду сторону Агат-контроллер, мне именно эта часть важна.

Но смысл этого чтения состоит, в общем-то, в том, чтобы очистить как раз флаг готовности.
И уже следующий байт читать, будучи готовым именно к чтению байта, а не анализу флага синхросбоя.

Да, это действительно так, я видел это в отладчике.

Voldemar0 пишет:

/* Байтрейт у 840ки близок к пределу 6502 и ждать или синхро или байт может не получиться по тактам. */

Т.е. этот читаемый байт будет мусорным, и, скорее всего, это будет $FF.

Повторил у себя последовательность FF, A4 с выставлением бита готовности на А4, ничего не изменилось.

> но драйвер его все-таки читает, далее читаем код 95, 65, FE, трек, сектор, 5А.

Voldemar0 пишет:

FE - номер тома, может быть и не FE. Зависит от фантазии того, кто создавал диск.
В общем-то, форматнуть диск номером тома отличным от fe довольно просто (в среде dos33 + Basic-60):

INIT HELLO, V121

Да, это понятно, но если я провильно понимаю, ни "драйвер" ни операционка не проверяет как-то этот байт, ну кроме того, что просто его читает?


> Но, алгоритм чтения 1 трека и последующих мне не понятен. Может кто прояснить, чем отличается чтение 0 трека от всех остальных?

Voldemar0 пишет:

Элементарно: на нулевом треке располагается полноценный драйвер, как только его прочитали, всё остальное (включая и хвост нулевого трека) читает уже он..

А есть где-нибудь описание всего того, что он делает? Мне нехватает понимания, что я сделал не так, драйвер работает, а операционка нет.
Вот что я вижу глядя на схему, можно перепрограммировать две 580ВВ55, можно включить режим вывода в порт С записав в регистр управления код 92 (С0У3) и в регистр RK слово его сотояния, а можно напрямую менять биты записав к регистр управлени (С0У3) 7-бит = 0, номер бита (3-1 биты) и установить/снять (0 бит). Тоже самое касается и Д15, но там в этом почти нет смысла, тк она должна работать в режиме 2.
Все, больше нам ничего для перепрограммирования недоступно, ну или я очень сильно ошибаюсь!

4 Отредактировано avivanov76 (10-05-2022 02:19)

Re: Вопрос по контроллеру 840К

zpilot пишет:

Да, это понятно, но если я провильно понимаю, ни "драйвер" ни операционка не проверяет как-то этот байт, ну кроме того, что просто его читает?

Операционка еще как проверяет. Этот байт нужен, чтобы понять, а не поменял ли пользователь диск в процессе записи. Потому что операционка не контролирует при каждой операции записи в файл, что он есть в каталоге. Это бы жутко замедлило работу. И если вставить другой диск, то данные запишутся без учета данных его VTOC и он будет испорчен.

Проблема только в том, что байт номера тома должен иметь случайное значение в момент форматирования. А по факту там всегда 254 и защита не работает.

zpilot пишет:

А есть где-нибудь описание всего того, что он делает?

Описания драйвера нулевого трека наверно нет. Он используется в основном начальными загрузчиками для загрузки составных частей программных пакетов. Многие пакеты, например, ИКП-шная Рапира, грузят RWTS (а точнее целиком DOS) отдельно. Почему так сделано - не знаю, но возможно у драйвера нулевого трека тоже не все функции реализованы.

Кроме того, ИКП-шный драйвер реализует некий аналог LBA - то есть, пара трек/сектор ему не нужна, он получает логический номер сектора. Возможно, это еще одна причина грузить RWTS отдельно.

5 Отредактировано Voldemar0 (10-05-2022 07:57)

Re: Вопрос по контроллеру 840К

> Этот байт нужен, чтобы понять, а не поменял ли пользователь диск в процессе записи.

Немного поясню: речь идёт о доступе к файлам в поблочном режиме: что-то вроде fopen(); fwrite(); fseek(); fclose();.

В агатовских доках этот режим не особо описан (только частный случай доступа к текстовым файлам).

Но общая суть в том, что в этом режиме операции открытия файла, чтения или записи и закрытия разнесены во времени.

Т.е. прога может быть открыла файл, что-то в нём исправила, потом пауза, общение с пользователем, дисковод отключен. Потом вновь вносятся какие-то изменения в файл. Вот когда дисковод остановлен, пользователь может не понять, что операция не закончена, и сменить диск. И операционка сразу же должна распознать этот факт.

Я думаю, тут расчёт был на то, что по умолчанию -то номер тома - 254, но именно если автор разрабатывает прогу, которая таким образом общается с диском, он при инициализации диска как раз и укажет какой нибудь том, отличный от 254. И тогда этот диск будет явно отличаться от других.
Способ не супер удобный и стабильный, но лучше чем ничего.

==


> А есть где-нибудь описание всего того, что он делает? Мне нехватает понимания, что я сделал не так, драйвер работает, а операционка нет.

Он - кто ? ROM драйвер был давно и подробно расписан Игорем Бончаном:

Так как возникает много вопросов по поводу работы контроллера Teac, решил
все-таки ответить всем и сразу. Читайте.

Листинг ПЗУ контроллера дисководов ЕС5323.01(02) (фг3.089.174) с
комментариями (Бончан Игорь)

В листинге все числа шестнадцатиричные

;=================================================================================================================================
C500: A2 20       LDX #20      ;оставлено на случай изменений в подпрограмме
C502: A0 00       LDY #00      ;FFCB (см. ниже) и совместимости между контроллерами, иногда выступает в роли ID

C504: A2 03       LDX #03      ;количество шагов головки внутрь
C506: 86 3C       STX  3C      ;кладем
C508: 20 CB FF    JSR  FFCB    ;идем на RTS (возврат из подпрограммы) в мониторе
C50B: BA          TSX          ;помещаем указатель стека в регистр X
C50C: BD 00 01    LDA  0100,X  ;в FF+X имеем WORD вектор, который остался после JSR FFCB (FF+X=0A, 100+X=C5 в нашем случае)
C50F: 0A          ASL          ;делаем это чтобы узнать слот контроллера (старший байт адреса - C0)
C510: 0A          ASL          ;сдвигаем этот байт в аккумуляторе (С5) влево на 4 бита (ASL)
C511: 0A          ASL
C512: 0A          ASL          ;имеем в аккумуляторе A=50
C513: 85 2B       STA  2B      ;теперь ячейка равна 2B=SLOTx10
C515: AA          TAX          ;и индексный регистр X тоже
;=================================================================================================================================
C516: A9 92       LDA #92      ;стартовая комбинация входных сигналов логики 1-го контроллера (чипа) КР580ВВ55А
C518: 9D 83 C0    STA  C083,X  ;считайте что это "full reset" !!! именно поэтому не надо при работе писать единицу в 7 разряд RK
                               ;конкретно: сброс режима предкомпенсации, сброс номера первого привода, выборка
                               ;неопределенного состояния тракта чтение-запись (2-й чип)
C51B: A9 BD       LDA #BD      ;стартовая комбинация входных сигналов логики 2-го контроллера (чипа) КР580ВВ55А
C51D: 9D 87 C0    STA  C087,X  ;также считайте за "full reset" !!! поэтому при работе с контроллером можно изменять лишь
                               ;биты 2 и 4, иначе, не зная конкретной схемотехники, вы получите непредсказуемое состояние
                               ;контроллера
C520: A9 0F       LDA #0F      ;7 бит RK в "1" - включаем НГМД
C522: 9D 83 C0    STA  C083,X  ;начал раскручиваться первый привод
C525: A9 09       LDA #09      ;в 4 бит RD пишем 1 - включаем разрешение формирования сигнала готовности чтения для тракта
C527: 9D 87 C0    STA  C087,X  ;проще говоря - режим чтения
C52A: EA          NOP          ;
C52B: EA          NOP          ;оставлено после правок и для совместимости с Волжскими контроллерами
C52C: A9 05       LDA #05      ;устанавливаем бит 2 регистра RK в "1" - направление движения головки "внутрь"
C52E: 2C A9 04    BIT  04A9    ;типичный прием для 6502 когда пойдем на C52F установим бит 2 RK в "0" направление
C531: 9D 83 C0    STA  C083,X  ;головки "наружу" (т.е. "0" во 2-й бит), устанавливаем RK
C534: 9D 89 C0    STA  C089,X  ;делаем шаг
C537: A0 08       LDY #08
C539: CA          DEX          ;задержка на успокоение головки
C53A: E4 2B       CPX  2B      ;выйдем с X таким же как и вошли
C53C: D0 FB       BNE  C539    ;N-разъема x 10
C53E: 88          DEY
C53F: D0 F8       BNE  C539    ;всего x*y $800 проходов
C541: BD 81 C0    LDA  C081,X  ;опрашиваем слово состояния (регистр S)
C544: 30 FB       BMI  C541    ;не готов, ждем (Флаг готовности "0" в 7 бите)
C546: C6 3C       DEC  3C      ;делаем 3 шага внутрь
C548: 10 EA       BPL  C534    ;(было по адресу C504:LDX #3,STX 3C)
C54A: 29 40       AND #40      ;а когда их сделаем будем приходить сюда
C54C: D0 E1       BNE  C52F    ;и ждать сигнала "0-й трек" (бит 6) ведь в 7 бите $3C будет "1" не менее $80
C54E: EA          NOP          ;раз, а это больше чем дорожек $50
C54F: 85 26       STA  26      ;сюда из аккумулятора "0" XFXXXXXXb AND 40 =0 (где F-сигнал "нулевой трек" регистра S)
C551: EA          NOP          ;уже говорил выше
C552: EA          NOP
C553: EA          NOP
C554: 85 41       STA  41      ;
C556: 85 3D       STA  3D      ;обнуляем все 26,41,3d
C558: A9 08       LDA #08      ;27=8, 26=0 (см.выше), это WORD вектор, по адресу 800 будет считан 0 сектор 0 дорожки
C55A: 85 27       STA  27      ;
;=================================================================================================================================
C55C: 9D 8A C0    STA  C08A,X  ;сбрасываем состояние синхротриггера (если не поняли ведь пока мы двигали головку и ждали
                               ;диск прошел далеко не один раз и не раз произошел сбой "синхро", секторов 20 прошло по минимуму)
C55F: BD 86 C0    LDA  C086,X  ;теперь ждем нового взвода синхротриггера
C562: 0A          ASL          ;выдвигаем на 1 бит влево - проверяем 6-й бит
C563: 30 FA       BMI  C55F    ;если не равен нулю (признак сбоя) то ждем
C565: BD 84 C0    LDA  C084,X  ;сбрасываем байт-мусора после сбоя (после синхро пишется байт из единиц FF, так как
                               ;нам нужно время после реакции синхротриггера, чтобы не зависеть от согласования схем тракта
C568: BD 86 C0    LDA  C086,X  ;теперь ждем первый рабочий байт после сбоя "синхро"
C56B: 10 FB       BPL  C568    ;байт сформирован ? ("1" в старшем 7 разряде - признак готовности байта)
C56D: BD 84 C0    LDA  C084,X  ;получен первый байт маркера пролога поля адреса (95 6A)
C570: C9 95       CMP #95
C572: D0 E8       BNE  C55C    ;нет будем идем на C55C, сбросим синхротриггер и все сначала
C574: 9D 8A C0    STA  C08A,X  ;сбрасываем синхротриггер (он ведь остался взведенным), отсюда и далее при стандартном чтении
                               ;появление сбоя синхронизации следует считать ошибкой в стандартном чтении (не в этом ПЗУ)
                               ;в конце чтения будет проверка сбоя "синхро"
C577: BD 86 C0    LDA  C086,X  ;следующий байт
C57A: 10 FB       BPL  C577    ;не готов
C57C: BD 84 C0    LDA  C084,X
C57F: C9 6A       CMP #6A      ;получили 2-й байт маркера пролога адреса
C581: D0 D9       BNE  C55C    ;нет, другой - ошибка, все сначала
C583: BD 86 C0    LDA  C086,X  ;1-й информационный байт поля адреса
C586: 10 FB       BPL  C583    ;не готов
C588: BD 84 C0    LDA  C084,X  ;это должен быть номер тома, но здесь он нам не важен, поэтому просто очищаем регистр R-данных
C58B: BD 86 C0    LDA  C086,X  ;2-й информационный байт поля адреса
C58E: 10 FB       BPL  C58B    ;не готов
C590: BD 84 C0    LDA  C084,X  ;это трек
C593: C5 41       CMP  41      ;в ячейке 41 первый записывали 0 (на C554), что первый раз проверяем нулевой ли трек
                               ;а потом (см. ниже) будем просто проверять на нужный (41) нам трек
C595: D0 C5       BNE  C55C    ;но если не совпадает: ошибка позиционирования или запись на дискете не верна, то так и
                               ;будем крутиться - перепозиционирования не будет, идем на риторическое C55C, и до упора
C597: BD 86 C0    LDA  C086,X  ;3-й информационный байт поля адреса
C59A: 10 FB       BPL  C597    ;не готов
C59C: BD 84 C0    LDA  C084,X  ;читаем
C59F: C5 3D       CMP  3D      ;нужный нам сектор? первый раз 3D=0 (см.выше), а потом просто ищем нужный нам
C5A1: D0 B9       BNE  C55C    ;нет, не тот сектор, идем искать поле адреса следующего
;=================================================================================================================================
C5A3: A0 00       LDY #00
C5A5: 84 3C       STY  3C      ;там был мусор после поиска 0-й дорожки
C5A7: 9D 8A C0    STA  C08A,X  ;сбрасываем синхротриггер, так как сбои синхронизации в разделителях GAP1 и GAP2 совершенно
                               ;естественное и множественное дело, ведь когда мы перезаписываем поле данных (запись любого
                               ;файла) информация в GAP'е нарушается и принимает вид, отличный от строки GAPxAAв после
                               ;исходного форматирования, так и появляются в GAP'ах сбои "синхро"
C5AA: BD 86 C0    LDA  C086,X  ;теперь ждем нового взвода синхротриггера
C5AD: 0A          ASL          ;выдвигаем на 1 бит влево - проверяем 6-й бит
C5AE: 30 FA       BMI  C5AA    ;если не равен нулю (признак сбоя) то ждем
C5B0: BD 84 C0    LDA  C084,X  ;сбрасываем байт-мусора после сбоя (после синхро пишется байт из единиц FF, так как
                               ;нам нужно время после реакции синхротриггера, чтобы не зависеть от согласования схем тракта
C5B3: BD 86 C0    LDA  C086,X  ;теперь ждем первый рабочий байт после сбоя "синхро"
C5B6: 10 FB       BPL  C5B3    ;не готов
C5B8: BD 84 C0    LDA  C084,X  ;получен первый байт маркера пролога поля данных (6A 95)
C5BB: C9 6A       CMP #6A
C5BD: D0 E8       BNE  C5A7    ;нет будем, значит в GAP2 висел мусор (совпадающий с маркером) идем на C5A7,
                               ;сбросим синхротриггер, и все сначала
C5BF: 9D 8A C0    STA  C08A,X  ;сбрасываем синхротриггер (он ведь остался взведенным), отсюда и далее при стандартном чтении
                               ;появление сбоя синхронизации следует считать ошибкой в стандартном чтении (не в этом ПЗУ)
                               ;в конце чтения будет проверка сбоя "синхро"
C5C2: BD 86 C0    LDA  C086,X  ;следующий байт
C5C5: 10 FB       BPL  C5C2    ;не готов
C5C7: BD 84 C0    LDA  C084,X  ;получили 2-й байт маркера пролога поля данных
C5CA: C9 95       CMP #95
C5CC: D0 D9       BNE  C5A7    ;нет, другой - ошибка, все сначала
;=================================================================================================================================
C5CE: 18          CLC          ;сбрасываем флажок переноса, для операции сложения при подсчете контрольной суммы (далее CHS)
C5CF: BD 86 C0    LDA  C086,X  ;начинаем читать собственно байты данных, помним что Y=0 (см. C5A5)
C5D2: 10 FB       BPL  C5CF    ;не готов
C5D4: BD 84 C0    LDA  C084,X  ;байт
C5D7: 91 26       STA (26),Y   ;напомню 26,27 - WORD адрес страницы, сюда читаем 256 байт данных (байт берем по индексу в Y)
C5D9: 65 3C       ADC  3C      ;добавляем к CHS
C5DB: 85 3C       STA  3C      ;пишем в ячейку (CHS=CHS+byte)
C5DD: C8          INY          ;индекс + 1
C5DE: D0 EF       BNE  C5CF    ;когда пройдем до FF в Y то FF+1=0, а пока Y<>0 читаем дальше
;=================================================================================================================================
C5E0: BD 86 C0    LDA  C086,X  ;читаем следующий байт
C5E3: 10 FB       BPL  C5E0    ;не готов
C5E5: BD 84 C0    LDA  C084,X  ;это байт - контрольной суммы (CHS)
C5E8: C5 3C       CMP  3C      ;сверяем с посчитанной
C5EA: D0 B5       BNE  C5A1    ;не совпадает идем через C5A1 на C55C BNE-BNE и перечитываем весь сектор и поле адреса и данные
C5EC: E6 27       INC  27      ;увеличваем старший байт адреса страницы с данными +1
C5EE: E6 3D       INC  3D      ;увеличиваем номер сектора +1
C5F0: A5 3D       LDA  3D      ;сверяем номер сектора с первым байтом прочитанного 0-го сектора 0-й дорожки (читали по адресу
C5F2: CD 00 08    CMP  0800    ;800) - в нем должно быть число секторов, которое должен прочитать контроллер до передачи
                               ;управления на следующий за этим байтом адрес, (т.е. 801)
C5F5: A6 2B       LDX  2B      ;еще раз в индексный регистр X=слот x 10, и если
C5F7: 90 A8       BCC  C5A1    ;номер прочитанного сектора меньше указанного в 800, то через C5A1 на C55C (BNE-BNE)
C5F9: 4C 01 08    JMP  0801    ;прочитали столько секторов, сколько было указано (800), передаем управление программе в
                               ;0-м секторе (смещение 1 байт)

C5FC: 01 02       ORA (02,X)   ;ID контроллера (02 - Teac)
C5FE: 34          ???
C5FF: 02          ???          ;контроллер НГМД

Вообще говоря, программа расположенная в ПЗУ является упрощенным вариантом
штатного чтения сектора и не проверяет сбоев синхро, не делает проверку
эпилогов, не учитывает число попыток чтения, не делает перекалибровки в
случае сбоя и т.п. Обычно в первом байте 0-го сектора (загрузчика) указан
байт 01, что подразумевает чтение лишь нулевого сектора. Почему? Это
связано с тем, что редко имеет смысл читать начальный код самозагружающихся
систем линейно, т.е.:

0-й сектор - адрес 800
1-й сектор - адрес 900
2-й сектор - адрес A00
3-й сектор - адрес B00
и т.п.

Обычно загрузчик сам управляет адресами загрузки в ячейке 27 возвращая
управление на C55C и принимая на 801.

Надеюсь, теперь вам все ясно.
Спрашивайте, хотя выходные уже заканчиваются.

Игорь.

Вообще, можно условно говорить о трёх драйверах:
- ROM-драйвер;
- Код, управляющий ROM-драйвером, уже после загрузки сектора 0/0, для чтения остальных секторов (эту штуку почему-то часто называли "автолоадер");
- RWTS (Read/Write Track/Sector) - полноценный, независимый от ROM, драйвер дисковода со всеми плюшками, записью, очередью команд и прочим.
Большинство операционок Агата используют все три вида драйверов.

> Мне нехватает понимания, что я сделал не так, драйвер работает, а операционка нет.

Так выложи свои наработки и поковыряем совместно.

Вообще, драйвер дисковода нынче - с появлением эмуляторов - не сложно отлаживать.
Но заканчивать отладку нужно обязательно на реальном железе.
Эмуляторы слишком предсказуемы, по сравнению с реальным железом.

> Все, больше нам ничего для перепрограммирования недоступно

Всё, что  я хорошо запомнил о программировании и режимах ВВ55 - это то, что те константы, которые приводятся в документации и драйверах - это единственная полезная комбинация и именно её используют все драйвера. Единственное, что мне доводилось видеть, расширяющее доки: в драйверах BTK есть такая штука: когда был сбой чтения, драйвер записывает режимные регистры какую-то константу, которая "распрограммирует" микруху (что-то типа состония "после reset"). Вроде бы идея в том, что при последующем старте драйвера он будет заного программировать микруху, тем самым сбрасывая всё, что можно сбросить. Но если ли в этом хоть малейший технический смысл - я не уверен.

6

Re: Вопрос по контроллеру 840К

avivanov76 пишет:

Проблема только в том, что байт номера тома должен иметь случайное значение в момент форматирования. А по факту там всегда 254 и защита не работает.

Драйвер 0 сектора точно пропускает этот байт, а вообще, согласен, очень логичное поведение.

avivanov76 пишет:

Описания драйвера нулевого трека наверно нет.

Ничего, я в отладчике его разобрал, это сделать не сложно, но вот с драйвером самой операционки - очень не просто, я вчера смотрел начальную загрузку операционки, те. на 0 дорожке это со 2 - по 15 сектор (кстати, почему всегда по 15, их же 21, но все что я видел, исползуют 0 дорогу только по 15 сектор), так вот, похоже, что она грузит код в область LC, и если это так то отладить это в этом эмуляторе:https://www.masswerk.at/6502/ невозможно.

avivanov76 пишет:

Кроме того, ИКП-шный драйвер реализует некий аналог LBA - то есть, пара трек/сектор ему не нужна, он получает логический номер сектора. Возможно, это еще одна причина грузить RWTS отдельно.

А где она берет этот номер? Или он его сама пересчитывает исходя из номера трека?

7 Отредактировано zpilot (11-05-2022 00:06)

Re: Вопрос по контроллеру 840К

Voldemar0 пишет:

>
Он - кто ? ROM драйвер был давно и подробно расписан Игорем Бончаном:

Спасибо за описание, я посмотрел и сравнил с тем, что я сделал сам в отладчике, СПАСИБО!!!
Но мне бы такое описание на код из операциоки.. есть подозрение, что у меня что-то не то с LC, возможно код операционки пытается прочитать номер трека или сектора  и сравнивает полученные данные с  данными которых не существует в природе, например, реальна такая ситуация, когда код операционки загружен в LC, ну или часть ее кода, которая работает с диском, она в процессе работы обращается к 0 странице, но что-то идет не так и вместо 0 страницы получает данные не из нее.. ну или думает, что из нее, а на самом деле получает просто  случайные данные.. Они, например, могут выйти за пределы реальных значений, но данные, которые операционка получает от контроллера фдд, правильные. Т.е. операционка из-за глюка с памятью будет требовать того чего нет.

Voldemar0 пишет:

Так выложи свои наработки и поковыряем совместно.

module fdd840(
    clk,
    clkf1,
    clkcpu,  // = f2
    res,
    
    test_points,
    
    io_on,
    rom_on,
    rw,
    
    address,
    din,
    dout,
    doutask,
    test,
    dot,
    
    addr_spi,
    ask_spi,
    byte_spi
);
input          clk;
input             clkf1;
input             clkcpu;
input             res;

output [ 7:0] test_points;// = {clkcpu,io_on,7'h55};
    
input          io_on;
input          rom_on;
input          rw;
    
input  [ 7:0] address;
input  [ 7:0] din;
output [ 7:0] dout;
output          doutask;
output [11:0] test = {tst[3:0],{3'd0,sec}};///{track[6:0],rkhead}};
output [ 2:0] dot  = {rkonfdd,sync_bit,byte_rdy};

output [23:0] addr_spi = (({16'd0,track[6:0],rkhead}*21+sec)<<8)+ bytessec;//{2'd0,track,rkhead,sec,bytessec};  
input              ask_spi;
input  [ 7:0] byte_spi;

assign test_points = io_on ? {c0y1,c0y3,c0y9,c0y6,c0ya,c0y4,byte_rdy,sync_bit} : {6'd0,byte_rdy,sync_bit};
//-----------------------------------------------------------
assign doutask = (romrd|iord)&clkcpu;//io_on & rw;
assign dout = romrd ? romdata : reg_data;

wire           romrd = rw & rom_on;
wire          iord  = rw & io_on;
wire          iowr  =~rw & io_on;

reg    [ 7:0] reg_data = 0;
reg   [ 7:0] tst =0;
//-----------------------------------------------------------
// S-reg
reg         srdy  = 1'b0;
reg         swp   = 1'b1;
reg  [1:0]fdd1 = 2'b00;
reg  [1:0]fdd2 = 2'b11;
wire         s0sec;
wire         s0trk;

wire [7:0]sreg = {srdy|(~rkonfdd),s0trk,swp,s0sec,fdd1,fdd2};
//-----------------------------------------------------------
// RK-reg
wire         rkonfdd;
wire         rkrw;
wire         rkpkon;
wire         rkhead;
wire         rkfddsel;
wire         rkdir;
wire         rknop;
wire        rkpk;
reg [7:0]rk = 8'h00;

assign {rkonfdd,rkrw,rkpkon,rkhead,rkfddsel,rkdir,rknop,rkpk} = rk;
//-----------------------------------------------------------
wire c0y1, c0y2, c0y3, c0y4;
wire c0y5, c0y6, c0y7, c0y8;
wire c0y9, c0ya;
fddaddr dc1(
    .data(address[3:0]),
    .enable(1'b1),
    .eq01(c0y1),
    .eq02(c0y2),
    .eq03(c0y3),
    .eq04(c0y4),
    .eq05(c0y5),
    .eq06(c0y6),
    .eq07(c0y7),
    .eq08(c0y8),
    .eq09(c0y9),
    .eq0a(c0ya)
    );
//-----------------------------------------------------------
// RD-reg
reg byte_rdy = 1'b0;
reg sync_bit = 1'b0;
wire rdy_rst_all = ~rkonfdd|rdy_rst|rdy_rst1;
wire sync_rst_all = (~rkonfdd|sync_rst)&(~rdy_rst1);
always @(posedge sync_set or posedge sync_rst_all)sync_bit <= sync_rst_all ? 1'b0 : 1'b1;
always @(posedge byte_clk or posedge  rdy_rst_all)byte_rdy <= rdy_rst_all? 1'b0 : 1'b1;
//-----------------------------------------------------------
//
reg [7:0] spin = 0;
wire         spinrst = ~rkonfdd|res|rst_dsk;
wire         motorrst = spinrst | spin[7];
always @(posedge clkf1 or posedge motorrst)spin <= motorrst ? 8'd0 : spin + 8'd1;

reg [7:0] step      = 8'd0;
reg [8:0] crc          = 0;
reg [7:0] diskdata = 0;
reg         sync_set = 0;
reg         rdy_rst1 = 1'b1;
wire          byte_clk = spin[7];

always @(posedge byte_clk or posedge res)
    if(res)begin
        step         <= 8'd0;
        crc         <= 0;
        //sec         <= 5'd12;
        bytessec <= 8'd0;
        diskdata <= 0;
        sync_set <= 0;
        rdy_rst1 <= 1'b0;
    end else begin
        sync_set <= 1'b0;
        rdy_rst1 <= 1'b0;
        //if(nextsec[5])begin step <= 8'd0; bytessec <= 0; 
        //                    sec <= sec<20 ? sec + 5'd1 : 5'd0;                                             end;
        case(step)
                 // track GAP1
                'd0  :if(bytessec<12)begin diskdata <= 8'hAA;bytessec <= bytessec + 8'd1;    
                                                    rdy_rst1 <= 1'b0;                                            end
                        else begin step <= 8'd1; bytessec <= 0; diskdata <= 8'hAA;
                                      rdy_rst1 <= 1'b0;                                                        end
                'd1  :begin step <= 8'd20; {sync_set,rdy_rst1} <= 2'b11; diskdata <= 8'hA4;end
                'd20 :begin step <= 8'd2 ; diskdata <= 8'hFF;                                        end
                'd2  :begin step <= 8'd3 ; diskdata <= 8'h95;                                        end
                'd3  :begin step <= 8'd4 ; diskdata <= 8'h6A;                                        end
                'd4  :begin step <= 8'd5 ; diskdata <= 8'hFE;                                        end
                'd5  :begin step <= 8'd6 ; diskdata <= {track[6:0],rkhead};                        end
                'd6  :begin step <= 8'd7 ; diskdata <= {3'd0,sec};                                    end
                'd7  :begin step <= 8'd8 ; diskdata <= 8'h5A;                                        end
                // GAP2
                'd8  :if(bytessec<4)begin diskdata <= 8'hAA;bytessec <= bytessec + 8'd1;    end
                        else begin step <= 8'd9; bytessec <= 0; diskdata <= 8'hAA;                end
                'd9  :begin step <= 8'd90; {sync_set,rdy_rst1} <= 2'b11; diskdata <= 8'hA4;end
                'd90 :begin step <= 8'd10; diskdata <= 8'hFF;                                        end
                'd10 :begin step <= 8'd11; diskdata <= 8'h6A;                                        end
                'd11 :begin step <= 8'd12; diskdata <= 8'h95; bytessec <= 8'd0; crc <= 0;    end
                'd12  :if(&bytessec)begin step <= 8'd13; diskdata <= byte_spi;
                                if(crc[8])crc <= ((crc +9'd1) & 9'b0_1111_1111) + byte_spi;
                                else crc <= crc + byte_spi;                                                end
                        else begin
                                diskdata <= byte_spi; bytessec <= bytessec + 8'd1;
                                if(crc[8])crc <= ((crc +9'd1) & 9'b0_1111_1111) + byte_spi;
                                else crc <= crc + byte_spi;                                                end 
                'd13 :begin step <= 8'd14; diskdata <= crc[7:0]; bytessec <= 0;                end
                'd14 :begin step <= 8'd15; diskdata <= 8'h5A;                                        end
                // track GAP3
                default: 
                        if(bytessec<21)begin diskdata <= 8'hAA;bytessec <= bytessec + 8'd1;    end
                        else begin step <= 8'd0; bytessec <= 0; diskdata <= 8'hAA;
                                      sec <= sec<20 ? sec + 5'd1 : 5'd0;                                end
                endcase
        end
//-----------------------------------------------------------
reg         ok_op    = 0;
reg         rst_dsk  = 0;
reg         sync_rst = 0;
reg         rdy_rst  = 0;
reg [5:0] nextsec  = 0;
reg [7:0] tstsg = 0;

always @(posedge clk or posedge res)
    if(res)begin
        track     <= 8'd1;
        sync_rst <= 1'b0;
        ok_op     <= 0;
        rk            <= 0;
        rst_dsk  <= 1'b0;
        rdy_rst     <= 1'b0;
        nextsec  <= 0;
    end else if(io_on) begin
        sync_rst <= 1'b0;
        rdy_rst     <= 1'b0;
        if(!ok_op)begin
            tst <= address[3:0];
            ok_op <= 1'b1;
            rst_dsk <= 1'b0;
            //-----------------------------------------------------------
            if(c0y1 & rw) reg_data <= sreg;
            if(c0y2 &~rw) rk <= din;
            if(c0y3 &~rw)
                if(!din[7]) begin rk[din[3:1]] <= din[0]; rst_dsk <= 1'b1; sync_rst <= 1'b1; nextsec  <= 0;    
                                        rdy_rst     <= 1'b1;                                                                                end
                else             if(din==8'h9B) begin rk <= 0; nextsec  <= 0;                                                    end
            if(c0y7 &~rw) begin if(din[7])tstsg <= 0; else tstsg[din[3:1]] <= din[0];                                 end
            if(c0y4 & rw) begin reg_data <= diskdata; rdy_rst     <= 1'b1;                                                 end
            if(c0y6 & rw) begin reg_data <={byte_rdy & rkonfdd,sync_bit & rkonfdd,6'd0};                             end
            if(c0ya & rw) begin sync_rst <= 1'b1; nextsec <= sync_bit | nextsec[5] ? 6'd0 : nextsec + 6'd1; end
            if(c0y9 &~rw) begin
                track <= rkdir ? track < 79 ? track + 8'd1 : 8'd79:
                                      track > 0   ? track - 8'd1 : 8'd0;
                rst_dsk <= 1'b1; nextsec  <= 0;                                                                                    end
            //-----------------------------------------------------------
            end
        end else ok_op <= 0;
//-----------------------------------------------------------
reg [4:0] sec = 5'd0;
reg [7:0] track = 8'd1;
reg [7:0] bytessec = 8'd0;

assign s0sec = (|sec)|(|step);//[4:1];
assign s0trk = |{track[6:0],rkhead};
//-----------------------------------------------------------
// boot rom
wire [7:0] romdata;
romfdd840 romfdd1(
    .address (address),
    .clock    (clk),
    .q            (romdata)
    );
//-----------------------------------------------------------
endmodule

Прошу только учесть, что код сырой, много отладки и не всегда нужных переменных.

8

Re: Вопрос по контроллеру 840К

Подскажите, нормальное прохождение теста Лисина и Теста памяти от ЛЭМЗ гарантирует отсутсвие проблем с диспетчером памяти и LC?

9

Re: Вопрос по контроллеру 840К

zpilot пишет:

Ничего, я в отладчике его разобрал, это сделать не сложно

Нет, я имел в виду описание того загрузчика, который находится уже на нулевом треке диска в секторах 1-15. Их есть много вариантов, к ИКП для Агат-7 вроде даже какие-то части исходников были, но подробных описаний к ним я не встречал.

zpilot пишет:

кстати, почему всегда по 15, их же 21, но все что я видел, исползуют 0 дорогу только по 15 сектор

Я думаю, для того, чтобы сделать загрузчик универсальным для 140К и 840К дисководов.

zpilot пишет:

похоже, что она грузит код в область LC, и если это так то отладить это в этом эмуляторе:https://www.masswerk.at/6502/ невозможно.

Разные загрузчики используют разные области памяти, но ИКП совершенно точно грузится в обычную память с адреса $9000 (на Агат-9). Область LC им самим не используется. Хотя части пакетов он туда загружать может.

zpilot пишет:

А где она берет этот номер? Или он его сама пересчитывает исходя из номера трека?

В ИКП-шном загрузчике есть таблицы для загрузки частей пакетов. В них указаны линейные номера секторов. И есть функция, которая из линейного номера сектора вычисляет пару трек/сектор.

zpilot пишет:

Подскажите, нормальное прохождение теста Лисина и Теста памяти от ЛЭМЗ гарантирует отсутсвие проблем с диспетчером памяти и LC?

Диспетчер памяти Лисин точно проверяет. Про LC навскидку не помню, но, скорее всего, тоже проверяет. Если 20-30 прогонов прошли без ошибок, то, скорее всего, проблем с памятью нет.

10 Отредактировано Voldemar0 (11-05-2022 06:51)

Re: Вопрос по контроллеру 840К

Я правильно понимаю: это попытка реализовать в железе некий контроллер, программно совместимый с 840кой, но использующий не дисковод для хранения данных ? Это стоило описать сразу, я думал что проблема в разработке собственного ROM-драйвера.

Т.е. ROM флопика у вас стандартный ?

Причем, я так вижу: вы пытаетесь реализовать в железе сразу синтез RAW-дорожки из DSK-формата ?
Опасная затея :) Читать вы так сможете, наверное, а вот когда полезет запись ... Там будет много ещё интересного ;))

...

Я бы, конечно, тут привлёк аппаратный отладчик, но так как это невозможно (если только вы в Томске живёте и у вашего агата есть хоть один типичный живой слот), то вариант дальше один: надо изучать содержимое озу после попытки загрузки.

Может быть есть возможность порыться в ОЗУ прямо на включенной системе в обход ЦП ?

В любом случае: самый первый ход: взять тест Лисина в виде образа (там где он с нулевого трека стартует) и убедится, что хотя бы он целиком загружается в память.

Он как раз использует многосекторную загрузку без всяких прочих хитростей.

А дальше уже договариваться о какой-то конкретной ОС, на которой идут тесты (не забывайте: под агата вагон софта и каждый имеет свои особенности, нужно обязательно указывать конкретный диск/образ, чтобы говорить предметно). Может быть специально модифицировать код для отладки.

---

Исходников загрузчиков полно, но комментариев там не сильно больше, чем в hex-дампе ;))
Да и не сильно они нужны - всё уже  изучено, обнюхано и рассмотрено :))

После загрузки сектора 0/0 загрузчик (с адреса $801) проверяет номер сектора или ещё какой нибудь флаг, что позволяет ему понять: был ли считан сектор 0/0 или какой-то другой ?

Если считан 0/0, то дальше автолоадер изучает конфиг аппаратуры (мы про семёрку или про девятку ?),
и начинает в цикле обращаться к ROM-лоадеру, чтобы тот прочитал хвост автолоадера: т.е. выдаёт ему номера секторов и адреса для загрузки. При этом передача управления выполняется на адрес Cx56 (лучше проверить, но это - константа , причем совпадающая для 840 и для 140- ROM-loaderов).

Если считан не 0/0, а последний нужный автолоадеру сектор, то дальше он может сам остановить дисковод или не делать этого.
После чего автолоадер инициализирует уже свой считанный RWTS, передаёт ему номер слота дисоковода (его можно вытащить из нулевой страницы) и затем дочитывает свой хвост с других треков или что там ему дальше надо, уже используя свой RWTS.

Это - общая, часто используемая, схема. Конкретнее можно рассказывать только если будет опубликован конкретный образ, который вы пытаетесь грузить.

---

Настоящий LBA у RWTS был только у ОС ONIX, больше вроде бы нигде его не было. Т.е. на уровне файловой системы.
Может быть где-то внутри Спрайт-ОС он тоже используется.

В ИКП если LBA и есть, то только у загрузчика меню. После того как оно отрабатывает, RWTS заменяется тем, который использует конкретная загруженная операционка.

В любом случае, в глубине драйвера всё пересчитывается сперва в трек/сектор, а потом и в трех/голова/сектор. Так что работа железа от этого никак не зависит.

---

В агатовской тусовке ходили диски с исходниками драйверов, и каждый автор использовал их как хотел.
Причем сделать какую-то существенную модификацию кода мог далеко не каждый, поэтому,
в итоге, сильно различающихся версий драйверов дисковода, терминала и всякого такого прочего было не очень много.
Но мелкие правки всё таки вносил для себя каждый, поэтому можно говорить о семействах
версий драйверов. Но внутри этих семейств код весьма похож, хотя и редко совпадает до байта.
А поскольку интернет не был доступен, то распространение шло не из одной точки, а цепочкой.
В результате один владелец делал правку, потом второй добавлял к ней свою правку,
третий отменял правку второго, но не так, как было в авторском варианте и т.д.
Даже если исходников не было, всё равно каждый школьник, изучивший ассемблер, считал
своим долгом подправить что нибудь в HEX-.

Так что даже если кому-то кажется, что, например, "ИКП" - это единственное и неповторимое и всем
понятное - то это не так. В нашей коллекции их уже десяток, если не больше и у каждого есть какие-то осбенности.
В т.ч. в автолоадере. И внешне они выглядят совершенно одинакого :))

11

Re: Вопрос по контроллеру 840К

Voldemar0 пишет:

Причем, я так вижу: вы пытаетесь реализовать в железе сразу синтез RAW-дорожки из DSK-формата ?
Опасная затея :) Читать вы так сможете, наверное, а вот когда полезет запись ... Там будет много ещё интересного ;))

Вот это он замахнулся...

Voldemar0 пишет:

В агатовской тусовке ходили диски с исходниками драйверов, и каждый автор использовал их как хотел.

К сожалению, у нас в Караганде таким даже и "не пахло"... Поэтому в своих поделках я юзал самописные RWTS, основанные на изучении "с пристрастием" штатной документации.

Турбо АГАТ-9/16 (ЦП 65C802, 5 Махов, dual-port SRAM).

12 Отредактировано Voldemar0 (11-05-2022 14:51)

Re: Вопрос по контроллеру 840К

> К сожалению, у нас в Караганде таким даже и "не пахло"... Поэтому в своих поделках я юзал самописные RWTS, основанные на изучении "с пристрастием" штатной документации.

Я сужу об этом по изучению собираемых коллекций.

А в Томске я занимался тем же самым: писал "умный"  дизассемблер, который умел подставлять метки вместо численных адресов, дизассемблировал ALV-шный форматтер, на основе его изучения собрал свой собственный RWTS.... И почти полностью перешёл на PC.
Так что результат этого исследования попал всего в одну прогу. А до этого использовал RWTSы, которые были внутри dos33 и внутри "отладочного комплекса". Даже делал что-то вроде условной компиляции в прогах, чтобы можно было компилировать их под обе эти среды.

13

Re: Вопрос по контроллеру 840К

Voldemar0 пишет:

Так что даже если кому-то кажется, что, например, "ИКП" - это единственное и неповторимое и всем
понятное - то это не так.

Кому? Мне? Мне точно не кажется :)
У меня сейчас вполне конкретная цель - понять устройство Рапиры до такой степени, чтобы осознанно поставить брейкпойнты и разобраться с этой багой при автозагрузке. Для этого мне пришлось разобраться как и куда она загружается с диска и с какого места начинает выполняться. Поскольку Рапиру я изначально выбрал ИКП-шную (как наиболее свежую и на самом емком носителе) то и загрузчик ИКП-шный пришлось поковырять основательно. Отсюда и подробности про ИКП.

Вообще, если почитать описание Цикозы, то видно, что ИКП-шный загрузчик - это просто загрузчик Рапиры "на стероидах". Меню вместо текстового сделали графическим, добавили второй драйвер дисковода и схему автовыбора. Для того, чтобы код загрузчика не зависел от формата диска добавили эту псевдо-LBA. А так в основе все то же самое, те же таблицы загрузки.

14 Отредактировано zpilot (11-05-2022 23:39)

Re: Вопрос по контроллеру 840К

Voldemar0 пишет:

Я правильно понимаю: это попытка реализовать в железе некий контроллер, программно совместимый с 840кой, но использующий не дисковод для хранения данных ? Это стоило описать сразу, я думал что проблема в разработке собственного ROM-драйвера.

Т.е. ROM флопика у вас стандартный ?

Причем, я так вижу: вы пытаетесь реализовать в железе сразу синтез RAW-дорожки из DSK-формата ?
Опасная затея :) Читать вы так сможете, наверное, а вот когда полезет запись ... Там будет много ещё интересного ;))

...

Я бы, конечно, тут привлёк аппаратный отладчик, но так как это невозможно (если только вы в Томске живёте и у вашего агата есть хоть один типичный живой слот), то вариант дальше один: надо изучать содержимое озу после попытки загрузки.

Может быть есть возможность порыться в ОЗУ прямо на включенной системе в обход ЦП ?

В любом случае: самый первый ход: взять тест Лисина в виде образа (там где он с нулевого трека стартует) и убедится, что хотя бы он целиком загружается в память.

Он как раз использует многосекторную загрузку без всяких прочих хитростей.

А дальше уже договариваться о какой-то конкретной ОС, на которой идут тесты (не забывайте: под агата вагон софта и каждый имеет свои особенности, нужно обязательно указывать конкретный диск/образ, чтобы говорить предметно). Может быть специально модифицировать код для отладки.

Да, в большенстве своем вы правы, я пытаюсь реализовать контроллер фдд на 840 кб, используя стандартный ROM контроллера ФДД (микросхема Д1). Я хочу отбросить только ту часть, которая преобразует из потока МФМ-данных в байт и заменить ее готовыми данными используя dsk образ.
О записи я пока не думал, мне нужно сделать чтение, чтобы продолжить доделывать свой синтезированный Агат-9.
Тест Лисина у меня грузится, а также грузится Теста памяти от ЛЭМЗ, все проходят без ошибок. Но мне кажется, что они весе умещаются в 0 дороге.
Насчет записи, запись сделать всегда проще, хотя бы потому, что данные выдает сам Агат, их только нужно правильно переварить, чтение не всегда предсказуемо, это я помню по контроллеру для УКНЦ, пытался эмулировать вп1-128, чтобы использовать стандартный драйвер, там все еще больше запущено чем на агате, там даже нет проверки полученного байта, все по времени считается..
Насчет содержимого, вот не могу его изучить, тк после перезагрузки агат начинает опять грузить с диска, а останавливать раньше чем загрузится 0 дорога нет смысла, тк данные будут не все, да еще и побъются ДК..
По поводу ОС, все что пробовал начиная с 1 дороги, все ведут себя одинаково, видят синхробайт, читают 4А,FF,95,65,FE,трек, сектор,5А и все.. ждут следующий сектор и так до бесконечности или выдат ошибку обмена.

15 Отредактировано zpilot (11-05-2022 23:28)

Re: Вопрос по контроллеру 840К

Вот немного фото с анализатора:
Чтение 0 дороги:

Spoiler

https://i.ibb.co/Vg7H3c8/photo1652021918.jpg

Чтение любой другой дорожки:

Spoiler

https://i.ibb.co/54JDZd2/photo1652021884.jpg

Белый - синхросбой, коричневый - байт прочитан, красный - Агат читает байт, желный - Агат читает регистр RD (c0y6), рыжий - Агат сбрасывает бит синхросбоя. Да, на этих фото нет последовательности 4А, ФФ, только 4А, но чтение от этого не изменилось, просто сигнал синхросбоя станет шире.

Spoiler

https://i.ibb.co/sP2mLzR/photo1652113510.jpg

Spoiler

https://i.ibb.co/d5mwN6w/photo1652132020.jpg

16 Отредактировано zpilot (12-05-2022 00:37)

Re: Вопрос по контроллеру 840К

Voldemar0 пишет:

Это - общая, часто используемая, схема. Конкретнее можно рассказывать только если будет опубликован конкретный образ, который вы пытаетесь грузить.

А можно у вас попросить взять любой, для вас удобный образ, для 9 Агата и расписать, что хочет его загрузчик? Достаточно одной не 0 дороги и 1 сектора с нее, можно вот так: ждем синхробайт, ждем пявления byteready, читаем, сбрасываем синхробит, ждем byteready, читаем 95... и т.д., 256 байт данных можно вообще пропустить.
Спасибо!
И ссылку на него, я попробоую с него загрузиться.

17 Отредактировано zpilot (12-05-2022 05:22)

Re: Вопрос по контроллеру 840К

Эх.. ну что же я такой не внимательный то?! Всех достал своими распросами.. Каюсь, я перепутал уровень сигнала синхросбой!!!! И из-за этого у меня так странно все читалось..


После того как синхросбой сделал активный-низкий, операционка стала видеть отличные от 0 треки, но загрузка оканчивается с зависанием, возможно, теперь косяк с данными..

18 Отредактировано Voldemar0 (12-05-2022 06:49)

Re: Вопрос по контроллеру 840К

>>    Так что даже если кому-то кажется, что, например, "ИКП" - это единственное и неповторимое и всем   понятное - то это не так.
> Кому? Мне? Мне точно не кажется :)

Не, я не о тебе, это больше к Zpilot. И к остальным, кто читает тему.
Просто уже не раз бывало, что вопросы касаются софта агата, пусть даже частоупотребляемого, но в обсуждении нет ни образа ни ссылки. И приходится выспрашивать - с чем же мы на этот раз имеем дело?


> разобраться с этой багой при автозагрузке.

Это о другой теме ?


> После того как синхросбой сделал активный-низкий, операционка стала видеть отличные от 0 треки, но загрузка оканчивается с зависанием, возможно, теперь косяк с данными..

Ты можешь остановить здесь ЦП и посмотреть последние шаги (адреса) ЦП ?

Давай я вечером возьму какой нибудь ИКП-бейсик, например и сделаю несколько образов с контрольными точками.
Попробуешь, и посмотрим, до куда оно дойдёт.

Опиши, что именно изображает твой агат ? Это девятка или семёрка или обе? Какая у него конфигурация ? В каких пределах можно менять конфигурацию?

У тебя в сисмоне и ЦП нормально обрабатывается команда BRK ?

Т.е. если в сисмоне написать, например:
5000:0
5000G
он должен ответить что-то вроде:
5002 - A=xx X=xx Y=xx ....

19 Отредактировано zpilot (13-05-2022 02:53)

Re: Вопрос по контроллеру 840К

Voldemar0 пишет:

Не, я не о тебе, это больше к Zpilot.

Я в Агатах ни в зуб ногой.. для меня , что ИКП, что не ИКП, вообще ни о чем не говорит, я вообще хотел просить ткуть меня носом в ссылку на этот ИКП, чтобы понять о чем речь..

Voldemar0 пишет:

Ты можешь остановить здесь ЦП и посмотреть последние шаги (адреса) ЦП ?

Давай я вечером возьму какой нибудь ИКП-бейсик, например и сделаю несколько образов с контрольными точками.
Попробуешь, и посмотрим, до куда оно дойдёт.

Теортетически могу, практически не знаю как остановить в нужный момент. В идеале загрузить бы с 0 дорожки, затем средствами ОС загрузить бы любую не 0 дорожку в известную область памяти и вывалиться в монитор. Чтобы посмотреть, что она загрузила, наверняка я ошибся где-то с арифметикой адреса нужного байта в дск-образе.

Voldemar0 пишет:

Это девятка или семёрка или обе? Какая у него конфигурация ? В каких пределах можно менять конфигурацию?
У тебя в сисмоне и ЦП нормально обрабатывается команда BRK ?

Я пытаюсь сделать синтез Агат-9, у меня сейчас 128 КБ памяти(sdram, вообще-то ее 8 Мегаслов, те она 16 битная и по этому нечетные блоки лежат в старших битах слова, сделано для облегчения вывода графического многоцветного режима, но он пока не реализован), ДК (реализованы Т32/64, и 2 монохромных графических), фдд контроллер, который я еще пытаюсь сделать..
Узел менеджера оперативной памяти и LC полностью повторяет оригинальный, я даже использую аналог ПЗУ (Д3, Д14)и РАМ (Д21).
Команда BRK отрабатывается так же как ее обрабатывает Агат.
Прерывания сейчас 60 и 600 Гц, но могу и 50/500 сделать, пока, я думаю, это не критично. Джойстиков/магнитофона/ком-портов пока нет/ДК от Эпла - нет.
Доделать не проблема, как это сделанное протестировать без загрузки ПО. Тем более, что загрузить его не такая уж и тривиальная задача. Потому нужен контроллер ФДД, без него подолжить не смогу, первоочередная задача.

Это мой Агат-9:

Spoiler

https://i.ibb.co/cwVmPk8/photo1652395078.jpg

Команда BRK:

Spoiler

https://i.ibb.co/K0fDZP8/photo1652395241.jpg

20 Отредактировано Voldemar0 (13-05-2022 04:58)

Re: Вопрос по контроллеру 840К

Хорошо, тогда начнём с этих образов.

example10.dsk:
example20.dsk:

Попробуй их запустить и расскажи или сфотографируй что получится.

example30.dsk:
ожидается останов в 083a.
После этого смотрим регионы памяти:

900L
A00L
B00L
C00L
D00L
E00L
F00L
*900L                             
                                  
0900-  AD 60 C1    LDA  $C160     
0903-  2C A9 00    BIT  $00A9     
0906-  8D 74 09    STA  $0974     
0909-  4C A7 09    JMP  $09A7   
090C-  A0 FA       LDY  #$FA      
090E-  8D 77 C1    STA  $C177     
0911-  9D 81 C0    STA  $C081,X   
0914-  B9 00 FF    LDA  $FF00,Y
0917-  8D 8B C0    STA  $C08B
091A-  8D 79 C1    STA  $C179
091D-  99 00 FF    STA  $FF00,Y
0920-  C8          INY
0921-  D0 EB       BNE  $090E
0923-  8D 5D C1    STA  $C15D
0926-  A5 4C       LDA  $4C
0928-  8D 4B BF    STA  $BF4B
092B-  F0 03       BEQ  $0930
092D-  20 15 C6    JSR  $C615
0930-  60          RTS
0931-  A2 0A       LDX  #$0A
0933-  20 0C 09    JSR  $090C
0936-  8D 66 C1    STA  $C166
0939-  8D 77 C1    STA  $C177
093C-  8D 83 C0    STA  $C083
093F-  A9 66       LDA  #$66
0941-  8D 9D 04    STA  $049D
0944-  8D A0 04    STA  $04A0
0947-  20 EF FB    JSR  $FBEF
*A00L                             
                                  
0A00-  30 FE       BMI  $0A00     
0A02-  8D C1 C8    STA  $C8C1     
0A05-  C5 CD       CMP  $CD       
0A07-  E2          ???          
0A08-  CF          ???            
0A09-  AE FB CF    LDX  $CFFB     
0A0C-  CE 5C 05    DEC  $055C     
0A0F-  10 09       BPL  $0A1A
0A11-  AD 70 08    LDA  $0870
0A14-  8D 5C 05    STA  $055C
0A17-  CE 5B 05    DEC  $055B
0A1A-  CE 60 05    DEC  $0560
0A1D-  C6 54       DEC  $54
0A1F-  D0 C9       BNE  $09EA
0A21-  A5 53       LDA  $53
0A23-  18          CLC
0A24-  69 05       ADC  #$05
0A26-  AA          TAX
0A27-  90 9D       BCC  $09C6
0A29-  60          RTS
0A2A-  73          ???
0A2B-  08          PHP
0A2C-  48          PHA
0A2D-  98          TYA
0A2E-  48          PHA
0A2F-  60          RTS
0A30-  08          PHP
0A31-  A9 83       LDA  #$83
*B00L                             
                                  
0B00-  13          ???            
0B01-  C8          INY            
0B02-  18          CLC            
0B03-  BD 86 C0    LDA  $C086,X 
0B06-  10 FB       BPL  $0B03     
0B08-  BD 84 C0    LDA  $C084,X   
0B0B-  65 26       ADC  $26       
0B0D-  85 26       STA  $26
0B0F-  C8          INY
0B10-  D0 F1       BNE  $0B03
0B12-  F0 A4       BEQ  $0AB8
0B14-  88          DEY
0B15-  BD 86 C0    LDA  $C086,X
0B18-  10 FB       BPL  $0B15
0B1A-  BD 84 C0    LDA  $C084,X
0B1D-  D1 3E       CMP  ($3E),Y
0B1F-  D0 BD       BNE  $0ADE
0B21-  C8          INY
0B22-  D0 F1       BNE  $0B15
0B24-  F0 92       BEQ  $0AB8
0B26-  A0 FF       LDY  #$FF
0B28-  D0 0B       BNE  $0B35
0B2A-  A4 2D       LDY  $2D
0B2C-  B9 48 07    LDA  $0748,Y
0B2F-  A0 01       LDY  #$01
0B31-  D0 04       BNE  $0B37
0B33-  A0 00       LDY  #$00
0B35-  A9 00       LDA  #$00
*C00L                             
                                  
0C00-  48          PHA            
0C01-  A0 FF       LDY  #$FF      
0C03-  8C 7E 05    STY  $057E     
0C06-  A9 00       LDA  #$00    
0C08-  20 0C 0C    JSR  $0C0C     
0C0B-  68          PLA            
0C0C-  A0 02       LDY  #$02      
0C0E-  D1 3C       CMP  ($3C),Y
0C10-  B0 ED       BCS  $0BFF
0C12-  85 26       STA  $26
0C14-  48          PHA
0C15-  88          DEY
0C16-  B1 3C       LDA  ($3C),Y
0C18-  10 0C       BPL  $0C26
0C1A-  4E 7E 05    LSR  $057E
0C1D-  68          PLA
0C1E-  4A          LSR
0C1F-  48          PHA
0C20-  A9 04       LDA  #$04
0C22-  2A          ROL
0C23-  9D 83 C0    STA  $C083,X
0C26-  68          PLA
0C27-  CD 7E 05    CMP  $057E
0C2A-  F0 3A       BEQ  $0C66
0C2C-  08          PHP
0C2D-  48          PHA
0C2E-  A9 02       LDA  #$02
0C30-  2A          ROL
*E00L                             
                                  
0E00-  EA          NOP            
0E01-  BD 8C C0    LDA  $C08C,X   
0E04-  10 FB       BPL  $0E01     
0E06-  C9 AA       CMP  #$AA    
0E08-  F0 5C       BEQ  $0E66     
0E0A-  38          SEC            
0E0B-  60          RTS            
0E0C-  A0 FC       LDY  #$FC
0E0E-  84 26       STY  $26
0E10-  C8          INY
0E11-  D0 04       BNE  $0E17
0E13-  E6 26       INC  $26
0E15-  F0 F3       BEQ  $0E0A
0E17-  BD 8C C0    LDA  $C08C,X
0E1A-  10 FB       BPL  $0E17
0E1C-  C9 D5       CMP  #$D5
0E1E-  D0 F0       BNE  $0E10
0E20-  EA          NOP
0E21-  BD 8C C0    LDA  $C08C,X
0E24-  10 FB       BPL  $0E21
0E26-  C9 AA       CMP  #$AA
0E28-  D0 F2       BNE  $0E1C
0E2A-  A0 03       LDY  #$03
0E2C-  BD 8C C0    LDA  $C08C,X
0E2F-  10 FB       BPL  $0E2C
0E31-  C9 96       CMP  #$96
0E33-  D0 E7       BNE  $0E1C
0E35-  A9 00       LDA  #$00
*F00L                             
                                  
0F00-  98          TYA            
0F01-  20 68 06    JSR  $0668     
0F04-  68          PLA            
0F05-  CE 86 05    DEC  $0586   
0F08-  D0 E5       BNE  $0EEF     
0F0A-  F0 CA       BEQ  $0ED6     
0F0C-  68          PLA            
0F0D-  A9 40       LDA  #$40
0F0F-  28          PLP
0F10-  4C 4D 0F    JMP  $0F4D
0F13-  F0 36       BEQ  $0F4B
0F15-  A0 03       LDY  #$03
0F17-  B1 48       LDA  ($48),Y
0F19-  48          PHA
0F1A-  A5 2F       LDA  $2F
0F1C-  A0 0E       LDY  #$0E
0F1E-  91 48       STA  ($48),Y
0F20-  68          PLA
0F21-  F0 08       BEQ  $0F2B
0F23-  C5 2F       CMP  $2F
0F25-  F0 04       BEQ  $0F2B
0F27-  A9 20       LDA  #$20
0F29-  D0 E4       BNE  $0F0F
0F2B-  A0 05       LDY  #$05
0F2D-  B1 48       LDA  ($48),Y
0F2F-  A8          TAY
0F30-  B9 66 0F    LDA  $0F66,Y
0F33-  C5 2D       CMP  $2D

example40.dsk:

Останова не будет, но к надписи "агат-9"
добавится "OK".

После появления мигающего курсора смотрим регион:

             AГAT-9OK           
*800.810                          
                                  
0800- 00 11 22 33 44 55 68 79     
0808- 80 90 A0 B0 C0 D0 E0 F0     
0810- 8B                          

И ещё важный вопрос:
как у тебя реализован регион C000.CFFF ?

Там должны быть вполне конкретные отклики, и чем больше прог планируется корректно работающих, тем этот регион должен работать точнее.
Особенно неиспользуемые ячейки, регионы слотов, к которым не подключены устройства и всякие прочие подробности.
Если expample30 проходит, а expampe40 - нет, то нужно подробно изучать этот регион.

Post's attachments

Attachment icon fr00.rar 204.44 kb, 136 downloads since 2022-05-13 

21 Отредактировано zpilot (13-05-2022 05:27)

Re: Вопрос по контроллеру 840К

как у тебя реализован регион C000.CFFF ?

Если я правильно понимаю, то имеется в виду, что возращается процессору в случае обращения по пустым слотам:

// free slots
wire free_slot = c200 | c400 | c500 | c600;
..
dii <= free_slot ? addr[15:8] : ...

Если слот не пустой, например Диспетчер памяти или LC, то возвращается либо подключеный банк памяти:
С110
С110 - 11
либо конфиг LC.

22 Отредактировано Voldemar0 (13-05-2022 05:42)

Re: Вопрос по контроллеру 840К

А по какому нибудь адресу вроде c040 что вернётся? Или по регионам C090..C0FF ?

23 Отредактировано zpilot (13-05-2022 05:49)

Re: Вопрос по контроллеру 840К

example10.dsk:

Spoiler

https://i.ibb.co/D1SgcQP/photo1652405860-9.jpg

example20.dsk, остановилось на этом:

Spoiler

https://i.ibb.co/9v9yXWM/photo1652405860-8.jpg

example30.dsk, остановилось на этом:

Spoiler

https://i.ibb.co/pWxVNZ3/photo1652405860-7.jpg

регионы памяти:

Spoiler

https://i.ibb.co/7C69j5h/photo1652405860-6.jpg
https://i.ibb.co/GR1NYbx/photo1652405860-5.jpg
https://i.ibb.co/t4fSZj6/photo1652405860-4.jpg
https://i.ibb.co/n7PyC0y/photo1652405860-3.jpg
https://i.ibb.co/pxRh4hb/photo1652405860-2.jpg
https://i.ibb.co/dL1s5gm/photo1652405860-1.jpg

example40.dsk:

Spoiler

https://i.ibb.co/C5L9dX5/photo1652405860.jpg

24

Re: Вопрос по контроллеру 840К

по регионам C090..C0FF

по всему диапазону (кроме фдд С0В0) возвращаются 0.

c040

Похоже на сбой с бегущей вверх звездочкой, бипером и выводом на экран BRK по 03FD.

25

Re: Вопрос по контроллеру 840К

Маленько продвинулись, вечером следующие образы подготовлю.
Вроде 40 пример правильно проходит и не зависает - уже хорошо.

> по всему диапазону (кроме фдд С0В0) возвращаются 0.
> Похоже на сбой с бегущей вверх звездочкой, бипером и выводом на экран BRK по 03FD.

с040 - включение таймера, если у тебя только сисмон в памяти, то всё просто зависнет (что мы и наблюдаем).
Но вопрос не об этом, вопрос в том, что процессор получит при чтении этого порта ?

Объясняю подробно:
алгоритмы определения оборудования ожидают вполне конкретные ответы от установленных устройств.
Если ответы соответствуют известным (например, контроллер дисковода опознаётся по 0 2 4 байтам ROM загрузчика сисмоном и по 4 последним байтам - при поиске некоторыми операционками),
то считается, что устройство присутствует. Иначе - отсутствует. Но это с контроллером флопа всё легко и просто - вряд ли 3-4 байта совпадут в случае отсуствия контроллера.
Для других устройств опрос иногда делается по одному байту. Если у тебя отствутвующие устройства будут отзыватся нулями или ещё каким-то случайным образом, алгоритмы могут глючить. Они и так-то могут глючить (например, пресловутый ИКП может стать неадекватным, если не найдёт ячейку принтера, но это не всегда (известная ошибка в его коде)), а уж на нестандартной аппаратуре - тем более.

Запиши и прибей на стену:

- У агат-7 любой порт, бит порта (даже не байт!) который не отвечает на запрос, возвращает 1. Например, порт кнопки джойстика использует только старший бит, он выставляется с кнопки пульта. Другие биты этого регистра будут 1. Если с040 включает таймер - это не значит, что кто-то при этом управляет шиной данных, а значит ЦП получит оттуда 0xFF. И т.д. Это обеспечивается группой pullup-резисторов на модуле ЦП.

- У агат-9 почти то же самое, за исключением того, что там разработчики сьэкономили 8 pullup-резисторов и поэтому проц при чтении неотвечающих портов, получает последнее состояние ША (т.е. из предыдущего такта). Как правило это будет старший разряд адреса. Т.е. у тебя c040 должен читаться как 0xC0, c800 - 0xc8 и т.д. Теоретически, в зависимости от команды чтения, наверное можно получить и другие значения, но обычно к Сxxx обращаются командами косвенной адресации, так что возвращать старший байт адреса в любом случае вполне хорошо.

Это касается, кстати, и регистра управления LC : C08x. Если посмотришь схему, там возвращается только 3 или 4 младших разряда, соответственно, остальные будут возвращаться из того же байта 0xC0.

Лисин этого не будет проверять, его вообще мало что интересует кроме модулей ДопОЗУ и базового ОЗУ. А вот операционки могут вести себя внезапно.

Возможно, конечно, что сейчас у тебя баг не в этом, но это тоже нужно исправлять.