Ну что ж, тема вроде как народ заинтересовала. Это радует.
Теперь я попробую изложить свои соображения по организации системы - я тоже этот вопрос долго обдумывал, особенно после изучения работы CP/N-90. Итак, выношу на обсуждение свою концепцию.
Загрузка системы. Вначале в корвет стандартным протоколом отсылается загрузчик 2 ступени. Это, собственно, уже реализовано на практике. Осталось написать сам загрузчик, так, чтобы он влез в 256 байт.
Потом загрузчик 2 ступени включает карту памяти 1С, переводит ВВ55 канал А в режим 2, и ждет. AVR берет файл образа системы с SD, отсылает загрузчику 2 байта размера файла, потом побайтово перекидывает сам файл и 1 байт контрольной суммы, на всякий случай. Загрузчик проверяет КС, отправляет в AVR байт подтверждения, и передает управление на точку входа BOOT. На этом загрузка окончена.
Взаимодействие BIOS с AVR. Нам потребуется встроить свой код в 3 системных вызова - READ, WRITE и SELDSK. Насчет первых двух - понятно. SELDSK - это функция выбора диска, с которым далее будут выполняться операции чтения-записи. Вроде бы фигня, но дело в том, что при первом обращении к диску с него считывается информационный сектор, и на его основании запоняется блок DPB. Причем считывается он прямым обращением к портам FDC. В начале образа KDI этот сектор, естественно, есть, его нужно прочитать и отдать биосу на разбор. Делать параметры диска фиксированными, как в CP/N90, нельзя - перестанут читаться диски МИКРОДОС.
Итак, все сводится к 2 запросам к AVR - чтение сектора и запись сектора. Многосекторные операции биос не поддерживает, ну и не надо. Получается, все взаимодействие с контроллером на уровне биоса сводится к 2 последовательностям:
Код:
R W
отсылка команды чтения отсылка команды записи
прием буфера с сектором передача буфера с сектором
Сам командный сектор получается совсем коротким:
Код:
cmd: DS 1 ; код команды, 1 - чтение, 2 - запись
drv: DS 1 ; # устройства, 0 - A, 1 - B
track: DS 1 ; дорожка
sector: DS 1 ; сектор
Всего 4 байта. Сектор данных - всегда 128 байт. Таким образом, стандартными средствами BIOS мы можем поддерживать образы дисков до 8М, что не так уж и мало.
Теперь командный протокол. Как выше обсуждалось, нам как минимум потребуются команда "монтировать KDI к устройству A или B". Остальные операции опциональны. ESL привел такой список:
дай мне список образов на диске
дай список того что смонтировано
загрузи бут с диска
прочитай конфиг
запиши конфиг
Первый и второй запрос - чисто информационные, чтобы знать, что у нас есть на карте и не монтировать вслепую. Насчет программной перезагрузки - я не знаю, насколько оно полезно. Перезагрузка легко делается кнопкой Reset, что проще, чем вводить команду reboot с консоли. А уж если система повисла намертво - никакое API уже не поможет ее оживить. Хотя реализовать-то это дело не особо сложно. Ну и конфиг - я так понимаю, предлагаешь хранить на карте список монтирования по умолчанию? Логично. Посмотрим, что в конце у нас получится, но идея хорошая. Для обращения к этому API из программ можно было бы сделать дополнительные точки входа в биос, но, я думаю, не стоит - достаточно сделать стандартную библиотеку и работать через нее. Само обращение к AVR будет реализовано через тот же 4-байтовый командный пакет, с кодом команды в поле CMD, за которым будет следовать блок с параметрами (имя файла образа итд).
Теперь о реализации BIOS. Мы будем поддерживать 4 диска. A, B - эмулируемые образы, C, D - реальные дисководы, если есть. Рамдиск E можно вообще из биоса выкинуть для освобождения места. Пользы от него в 21 веке уже никакой.
Есть 2 варианта реализации. Первый предложил выше ESL - взять готовый двоичный биос, напихать наш код в свободные дырки в коде, и поставить ссылки на него в точках вызова API. Так было сделано в CP/N-90, правда, за счет кастрации многих подсистем BIOS. Путь очевидный, но не слишком удобный - распихивать код по дырам - это как-то немного унизительно
ESL, ты привел впечатляющий список дыр одного из биосов. Можешь показать, в каком из файлов твоих баз лежит этот биос? Я бы сам хотел глянуть. Дело в том, что в том биосе, который ковырял я, что-то не видно таких шикарных промежутков. Есть только щели в несколько десятков байт на месте зарезервированных таблиц. Естественно, дыры должны быть именно в BIOS - выше DA00. BDOS и CCP перезагружаются с диска при каждом рестарте системы, и код туда помещать, понятно, нельзя. А килобайтная дырка - это уже немало, пожалуй, в килобайт можно запихать почти все.
Или я тебя неправильно понял, и это не список дыр одного биоса, а список размеров дыр в каждом из известных тебе биосов? А дыра в биосе всего одна. Хотелось бы только посмотреть, где она находится.
Второй путь. Собрать BIOS с нуля из исходных текстов. К сожалению, исходников нормального биоса от CP/M я не нашел. Есть только огрызки от МИКРОДОС, лежащие у ESL в архиве с IDA базами. Исходники настолько странные, что мне проще разобрать работу кода по IDA-базе, чем по ним. Но есть еще один вариант - экспортировать ASM-файл из IDA-базы. И потом найти ассемблер, который сумеет сожрать эти исходники. Если все получится - это будет то, что надо. Тогда наш код можно встраивать напрямую в функции BIOS без всяких патчей. Только для этого нужно докопать код - чтобы везде, где нужно, стояли ссылки на метки вместо абсолютные адресов. К сожалению, разработчики вовсю пользовались грязнейшими хаками типа самомодифицирующегося кода и даже передачи управления в середину машинной команды! Уроды блин. Хотя это больше относится к ОПТС, биос вроде почище. В любом случае, я в выходные попробую заняться чисткой кода в базе. Если уж не получится - пойду по пути, прделоженному ESL, с патчем биоса в двоичном виде.
На выходных съезжу на дачу, там у меня валяется несколько дохлых кардридеров. Надо выдрать SD-гнездо, и поключить наконец к меге. ESL привел пример схемы. Она, собственно, совершенно тривиальна - карта подключена к порту SPI, через делители из сопротивлений для согласования уровней. Вот этих делителей я и хотел избежать. Во-первых, 6 лишних резисторов на плате. Во-вторых, эти самые делители искажают фронты сигнала, что иногда приводит к странным вещам. Но более простых путей, похоже, нет. Понизить питание меги до 3v нельзя - для нее станут опасными 5v TTL-уровни от корвета.
То, что мне очень не хотелось делать - драйвер vfat. Я посмотрел на предложенную PetitFS - вроде бы неплохая реализация. Держит 2 открытых файла параллельно - то что надо. Но придется ее разбирать детально - я стараюсь не использовать у себя чужой код втемную, всегда хочу понять как он работает. Может быть, окажется, что проще свое написать.
---------- Post added at 09:06 ---------- Previous post was at 08:59 ----------
Да, кстати.
Сообщение от
esl
на РМУ нет принтерного порта
Разъема для принтера нет. А сам порт - это же канал А ППИ2. Он есть на всех корветах, куда он денется... Вот его вполне можно использовать для теста шины.
Я смотрю, ты extrom уже приделал к эмулятору. Только ты как минимум файл ext_rom.h забыл в дерево положить