Передовица » Агат ↔ PC » Линк N 1 » Теория

Теория

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

Немного о существующих и возможных решениях

Что соединять и с чем ? И PC и Агат имеют много разных интерфейсов, которые можно использовать. Вот например, со стороны Агата: интерфейс клавиатуры (только ввод), интерфейс пультов (более медленный чем клавиатура, но теоретически можно использовать в оба направления), интерфейс видеосистемы (только вывод, сложности с декодированием), интерфейс магнитофона (медленный, но простой в использовании), дисковод (обсудили), системная магистраль (очень быстро, но сложно в использовании), модуль универсального последовательного/параллельного интерфейса (только у семёрки), модуль принтера (только у девятки) - достаточно удобны.

Со стороны PC: системная магистраль (ISA, PCI - безумно быстро, но PCI - неприлично сложно), звуковая карта (неторопливо, но перспективно), клавиатура (два направления, но бессмысленно), LPT и COM-порты (очень удобно и быстро), USB (безумно быстро, но неприлично сложно), PATA-IDE (почти так же как и LPT, но внешнее устройство должно обладать приличной скоростью реакции), floppy (уже обсуждалось).

Остановимся подробнее на четырех интерфейсах.

Магнитофонный вход удобен тем, что в ПЗУ Агата есть поддержка этого интерфейса. Со стороны PC магнитофонного порта нет, зато есть звуковая карта. И в качестве медленного соединения на первоначальном этапе работы это может быть использовано. Однако, в процессе написания этой странички обнаружилась странная штука: если в семёрке магнитофонный вход нормально поддерживается как ПЗУ-версией системного монитора, так и Бейском, то в девятке из Бейсика поддержку магнитофона исключили (ну это ещё как-то можно понять), а в ПЗУ - допустили серьёзную ошибку (в таблице адресов процедур-обработчиков команд хранится только младшая часть адреса, старшая предполагается равной ¤FE, но как раз код чтения блока вылетел за пределы этой страницы и попал на страницу ¤FF. Таким образом передача управления по команде "R" происходит совсем не туда, куда надо), которая приводит к невозможности обратиться к драйверу стандартными командами. Причём в ПЗУ девятки, судя по всему, остался лишь код, необходимый для чтения блока данных и записи одного бита. Код записи блока данных потерялся.

Порт клавиатуры Агата можно использовать также на начальном этапе для перекачки софта из инета на Агат (подключив его к LPT порту PC). Удобство то же, что и у магнитофонного порта: есть поддержка клавиатуры в ПЗУ. Но я таких экспериментов не проводил.

LPT и COM-порты PC одинакого удобны, хотя считается, что COM-порт менее подвержен разнообразным отказам из-за воздействий разного рода статических разрядов и кривых пальчиков косолапых ручек пользователей. Не знаю у кого как, у меня на всех машинах работают все порты, несмотря на мою деятельность.

Однако LPT порт желательно использовать вместе с параллельным интерфейсом семёрки, либо с портом принтера девятки, а COM-порт может быть использован только с COM-портом семёрки (если отказаться от разнообразных доработок и использовать только прямые кабельные соединения).

LPT интерфейс быстрее клавиатурного и магнитофонного, поэтому именно его я выбрал в качестве основного. Но если вы повторяете мою конструкцию, вам нужно будет каким-то образом передать код управления портом на Агат (скачав его с этой страницы). Для этого вы можете либо просто набрать его с клавиатуры Агата, либо соединить магнитофонный порт Агата с выходом звуковой карты PC и воспроизвести файл с записью драйвера.

Судя по отзывам из инета, на просторах 1/6 части суши остались, преимущественно, девятки. Поэтому и линк, предложенный на этой странице, сделан именно под парпорт принтера, которым комплектовался 9-й Агат. Хотя ничто вам не мешает, добыв плату этого порта, воткнуть его в семёрку - линк будет работать и в такой конфигурации (именно так я его отлаживал).

У меня есть конструкции линков и под седьмой Агат (точнее, под его плату IO), но они не доведены до качества, достаточного для публикации. Кроме того, там работа шла в направлении ускорения обмена и агатовская плата порядочно дорабатывалась. А на этой странице опубликова предельно простой для повторения вариант.

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

Протокол канала

К большому сожалению, Агат-9 не имел в штатной поставке последовательного полнодуплексного порта, как это было у семёрки. С другой стороны, микросхема последовательного порта семёрки тоже была не ангелом с крылышками, и очень плохо работала на приём в случае хотя бы незначительного рассогласования скоростей (современные порты rs232 в этом случае умеют делать некоторую автоподстройку) и вообще, плохо переваривала на приём скорости выше 10000 кбит/с (хотя передавать могла хоть на 115200). Но даже при всех этих недостатках, она обеспечивала аппаратный двунаправленный обмен, которого нет у парпорта девятки.

Раз нет аппаратного, приходится делать программный. Теряя в скорости и усложняя код управления. В чём проблема ? Основная проблема - рассинхронизация программ с двух сторон. Например: агат хочет принять байт и PC хочет принять, хотя должна передавать. Ну случилось так... И обе висят. И друг на друга внимательно смотрят. Или наоборот - оба вдруг решили чего нибудь передать. И обе ждут готовности для приёма. Пока им ресет не нажмут.

Эту проблему я решил так: транзакция передачи всегда обеспечивает взаимообмен. Т.е. нет отдельной операции приёма или передачи полубайта (ограничения парпорта: принимать он может только 8 бит, один из которых служебный, 4 - данные и 3 - не используются. Это диктуется схемой кабеля и вполне разумно, хотя и не обеспечивает предельную скорость), транзакция всегда подразумевает одновременную пересылку полубайта в обе стороны. Таким образом, что бы не хотели сделать обе стороны - принять или передать данные, драйвера нижнего уровня не зависнут. В случае последовательного порта эта проблема решалась бы аппаратно.

Второе: как же всё таки опознать ситуацию с рассинхронизацией данных (т.е. когда одна сторона передает или ожидает совсем не то, что в данный момент её передаёт другая сторона) ? Для этого служит синхронизация высокого уровня. Машины в этой фазе взаимно обмениваются несколькими известными константами. Отправив одну константу, код ожидает другую. Если он получит не то, что ожидает, вновь перейдёт к началу процесса синхронизации. Это не сходящийся алгоритм (т.е. самостоятельно машины из него не выйдут), но он позволяет блокировать обмен, если что-то пойдёт не так. В случае рассинхронизации PC-шная сторона выводит об этом сообщение и останавливается до нажатия Enter, агатовская сторона же просто переходит к ожиданию начала синхропоследовательности.

Нажатие любой клавиши на Агате, кроме F1, также сбрасывает сервер в состояние ожидания синхронизации. Если при этом был включен русский язык (РЕГ-РУС) сервер начинает постоянно менять бит готовности, что рано или поздно также приведёт PC-шную сторону в состояние ожидания синхронизации. Переключение клавиатуры Агата на латинскую раскладку (РЕГ-ЛАТ) возвращает сервер в режим нормального функционирования.

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

Третье: данные могут поступать в нужном порядке, но с искажениями. На этот случай в протоколе предусмотрена контрольная сумма (8 бит на каждые 256 байт при передаче сектора диска и 8 бит на 4 байта в фазе передачи команд), дублирование информации (при передаче сжатого сектора). Контрольная сумма считается как xor всех байт, это не идеальный способ (например, "зависание" одного бита порта в состоянии "0" гарантированно не будет обнаружено при такой проверке), но лучше, чем ничего.

Больше подробностей можно увидеть в комментариях исходников.

Это был вид снизу, теперь вид сверху. Софт пострен таким образом, что Агат является сервером, PC - клиентом. Т.е. Агат обслуживает запросы PC и к его клавиатуре подходить не обязательно. Агат сам не инициирует какого либо обмена.

Инициировать может только PC. В начале она должна передать код синхронизации: четыре раза повторяется взаимообмен полубайтами-константами. Если он завершился успешно (т.е. приняты ожидаемые константы), PC передаёт пакет управления: код операции, два дополнительных байта (обычно, трек и число секторов) и контрольную сумму пакета. Если со стороны Агата тест контрольной суммы прошел успешно, он передает байт готовности к операции и затем выполняет её. Сейчас есть шесть операций: закрыть сервер, изменить текущий привод или контроллер дисковода, считать дорожку быстро, считать дорожку точно, записать дорожку быстро, записать дорожку точно.

Разделение на точный или быстрый обмен появилось в поздних агатовских операционных системах. Суть в том, что быстрый ("ленивый") обмен - это, фактически, кеширование запросов, т.е. откладывание их до накопления. Например, накопление запросов ко всем секторам дорожки. В этом случае драйвер дисковода будет обслуживать сектора в том порядке, в котором они будут появлятся под головкой дисковода, чем гарантирует полный обмен с треком в пределах одного оборота диска. Это позволяет иметь предельно высокую скорость обмена и забыть о факторе чередования секторов (PC отдыхает).

Но есть проблема: я так и не нашел возможности получить у стандартного драйвера RWTS данных о том, какие сектора прочитались с ошибкой в ленивом режиме. Т.е. драйвер возвращает лишь среднюю температуру по больнице: "кажется, что-то не прочиталось". Поэтому ввёл точный режим: кеширование запрещается, результат возвращается для каждого сектора. На старых операционках это был единственный режим работы и действовал он довольно быстро. На новых операционках он весьма медлителен. :(( Но для архивных/раритетных дисков ничего лучше не придумалось.

Возвращаемся к протоколу. После выполнения операции (чтения или записи) происходит обмен данными. Машина-источник перед передачей очередного сектора анализирует его и если все байты заполнены одинаковым числом, будет передан только признак сжатого сектора и затем байт, которым заполнен сектор. Если же содержимое сектора сложнее, передаётся признак несжатого сектора и все 256 байт данных. Алгоритмов типа RLE я реализовывать не стал, рассудив, что сложный анализ данных на стороне Агата может потребовать не меньше времени, чем их передача.

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

Неправильно прочитавшийся сектор со стороны Агата будет передан как 256 байт со значением 0xBD (точнее, буфер будет сначала заполнен этой константой, а затем передан как сжатый). Этот признак понимает, как минимум, DOS33.EXE - утилита для работы с образами дисков и blender.exe - программа для сведЕния образов одного и того же диска, сделанных на разных дисководах (с целью минимизации ошибок чтения). Сектор, присланный с PC, но который Агат не смог записать на диск, никак не влияет на обмен между машинами, лишь на мониторе Агата этот сектор будет помечен буквой E, но даже это произойдёт только в режиме точной записи.

Так как обмен с диском со стороны Агата происходит с использованием стандартных драйверов дисковода, любая информация сверх пользовательских данных (т.е. всякие специальные/служебные байты, которые использовались в защитах программ от копирования) будут потеряны. Со стороны PC данные представляются в виде образов дисков размером 143360 или 860160 байт.

Программное обеспечение

Софт для Агата представлен в виде одного исходного текста, который можно, в зависимости от значения переменной DOSTYPE, компилировать для четырех целевых платформ: 1) каноническая ОС семёрки (в которой бейсик лежал в отдельном файле HELLO, размером 59-60 блоков) - значение DOSTYPE EQU DT_DOS33, версия линка D7, 2) отладочный комплекс ОС Школьница (она грузилась с дискет 140к, в меню выбор только из трёх пунктов: Рапира-интерпретатор, Отладочный комплекс, Копирование дисков) - значение DOSTYPE EQU DT_DOK, версия линка A7, 3) любой бейсик-ИКП (он может быть как в составе ИКП так и существовать самостоятельно и всегда хранится вне файловой структуры на младших дорожках диска) - DOSTYPE EQU DT_DOS9, версия линка D9, 4) отладочный комплекс из состава ИКП ("Ассемблер") - DOSTYPE EQU DT_DOK9, версия линка A9.

В основном, версии отличаются тем, что обращаются к драйверу RWTS в соответствии с протоколом, принятом для конкретной ОС, также в различных ОС отличаются точки входа в процедуры управления дисплеем. Отладочные комплексы различаются между собой весьма незначительно (с точки зрения линка и пользователя), а вот Бейсики с соответствующими операционными системами совпадают (и то не совсем) только в протоколах обращения к дисководу.

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

Вторые две платформы существуют как в версиях для семёрки так и для девятки. Обе платформы умеют оперировать с дисками 140к и 840к, но в режимах точного обмена весьма медлительны. Исполняемый код линка не зависит от аппаратуры: например, версия для отладочного комплекса ИКП будет работать там, где заработает сам ИКП - независимо от того, будет ли это семёрка или девятка (но сам по себе ИКП существует в разных версиях - как для семёрки так и для девятки !).

Второй байт (т.е. по абсолютному адресу ¤2901 после загрузки линка) содержит номер слота * ¤10, в котором установлен контроллер принтера. By default это ¤60 - шестой слот, в таком виде я отлаживал линк на семёрке. Но у девяток стандартно контроллер принтера сидит в четвёртом слоте, в таком случае нужно сменить эту цифру на ¤40.

Со стороны PC софт существует для MS-DOS-совместимой системы и для FreeBSD (скомпилировать его под Linux можно, но нужно немного подправить процедуру доступа к LPT-порту - у Linux, кажется, нет аналога фришного драйвера /dev/ppi). Исходные тексты для обеих операционок различны, исходной является C-шная версия для FreeBSD, Pascal-версия для MS-DOS вторична. Для упрощения кода часть параметров задаётся в виде констант-макросов, что приводит к необходимости иметь несколько версий загрузочного кода (фактически, отличающихся лишь параметрами некоторых процедур).

Предполагая, что софт линка для FreeBSD будет востребован Интернет-сообществом редко, ссылка на него вынесена на эту страницу: 33 Кб.

Ключи управления фришной версией клиента мало отличаются от MS-DOS-версии:

  • ./mv800 -r IMAGE.DSK - для получения образа диска в файл IMAGE.DSK, если текущий дисковод 840к.
  • ./mv140f -r IMAGE.DSK - для быстрого получения образа диска в файл IMAGE.DSK, если текущий дисковод 140к.
  • ./mv800f -t IMAGE.DSK - для быстрой отправки образа диска из файла IMAGE.DSK, если текущий дисковод 840к.
  • ./mv140 -t IMAGE.DSK - для отправки образа диска из файла IMAGE.DSK, если текущий дисковод 140к.
  • ./mv140 -d 31 - смена текущего дисковода на дисковод SLOT=3, DRIVE=1 (для версий линка MV-D7, MV-D9, MV-A7).
  • ./mv140 -d 2 - смена текущего дисковода на дисковод # 2 (для версий линка MV-A9).

Софт линка для ms-dos: 16 Кб.

Софт линка для Агата, в различных форматах:

ОписаниеВерсия
MV-D7MV-A7MV-D9MV-A9
Исходные тексты (в формате КОИ-8 и АГАТ-КОИ) и скомпилированные варианты драйвера в FIL-формате. FIL-формат понимает dos33c2.exe, кроме того, просматривая этот файл со смещения 0x2C, можно просто набрать его с клавиатуры на Агате. 12 Кб
Скомпилированный драйвер в виде звуковой дорожки, которую можно подать на магнитофонный вход Агата. Формат MP3. Файлы закатаны в zip-архив на случай, если различные firewallы блокируют передачу MP3. ~130 Кб ~130 Кб ~130 Кб ~130 Кб
То же звуковая дорожка, но уже в формате WAV. У меня Агат одинакого успешно считывал и WAV и MP3, но на всякий случай я решил опубликовать и несжатый вариант. ~950 Кб ~950 Кб ~950 Кб ~950 Кб

Файлы звуковых дорожек могут читаться Агатом по команде 2900.2CFFR, но, как сказано выше, у девятого Агата, из-за ошибки в ПЗУ, эта команда не выполняется и приходится писать небольшую "вызывалку", описанную в "первом варианте". Она задаёт значения переменных в области ¤3C..¤3F (задать их с командной строки Системного Монитора невозможно, так как эти ячейки используются Монитором) и затем вызывает процедуру чтения по адресу ¤FF07, предварительно подключив на эти адреса ПЗУ.

Использование материалов проекта agatcomp без получения предварительного письменного разрешения agatcomp запрещено.


Почта для обратной связи: mail@agatcomp.ru


Живое общение по теме Агата: Telegram группа Agatcomp.


Накопленные знания и проекты: тематический ФОРУМ.


© 2004-2024 agatcomp.su / agatcomp.ru

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *