В принципе вопрос по адресу (т.к я трансляцию CP/M для кучи 8-ми разрядок делал много раз), но как нужно я не в курсе (не читал вражьих форумов на эту тему, т.к не имел Интернета). Могу рассказать лишь как это делаю я. В принципе, полезно что-то такое написать (пока я ещё жив), а то вижу, как некоторые собирают CP/M в более примитивных вариантах и неудобным способом.PVV wrote:... заодно, пошагово рассказать, как нужно собирать файлы CP/M
Не важно для какой это конкретно машины, как пример, думаю повести речь о CP/M Специалиста, т.к это я делал относительно недавно (года 2 назад) и есть (или по крайней мере был) эмулятор EMU80, где это можно было посмотреть, причём и при работе на эл.диск из дополнительного ОЗУ (которого у обычного Специалиста нет) и при работе на РК-КНГМД. Сделать CP/M с работой на КНГМД с ВГ93 (по любому из 4-х изощрённых вариантов КНГМД) на базовый Специалист с клоком всего 2 МГЦ - пока не могу (и из вариантов лишь КНГМД от Специалиста-MX вроде бы эмулируется).
Хотя чужие подпрограммы для этих вариантов я выдрал из соответствующих версий DOS Специалиста, но не использовал, не проверял в реале. Пока для ВГ93 я могу гарантировать лишь, что корветовские подпрограммы на корветовском же КНГМД будут работать, но это годится лишь для турбированного до 2.5 МГЦ Специалиста. Да и EMU80 не поддерживает пока контроллер на БИС ВГ93. Клок 2.5 МГЦ плющит экранчик.
Чтобы странслировать работающую версию CP/M даже не нужны ВГ93-дисководные или винтовые подрограмм (они у меня тоже есть: в двух вариантах для ВГ93 и одном для IDE-винта). Достаточно написать простейшие подпрограммы для эл.диска из ОЗУ (основного или дополнительного).
По сути адаптация CP/M под конкретное железо заключается лишь в настройке параметров (т.е адресов, где размещаются блоки и другие константы), настройке консольных п/п-мм CP/M-BIOS, а основной объём работ сводится к получению подпрограмм чтения и записи сектора (а в случае эл.диска и форматирования его). Подпрограммы чтения/записи в моих исходниках CP/M для физически разных носителей располагаются в инклюдах - FLOP.INC (или RKFLOP.INC), VDISK.INC и VINT.INC.
CP/M я обычно гружу не из дискеты как было принято в 70-тые, а из ROM-диска (но не проблема тот же код считать и с дискеты). И, также (но это моя "фишка", не стандарт CP/M) в BIOS, для многобанковых машин (или ROM-диск версий) я модифицирую процедуру Warm Boot, чтобы по горячему рестарту BDOS и CCP подкачивались не с дискеты, а из специального буфера (в другой банке или из ROM-диска). Это приводит к тому, что на дискетах не нужны системные дорожки (но и не вредят), не надо держать на них код CP/M и возникает всеядность дискет.
Подпрограммы в BIOS для чтения/записи лог.блока называются READ и WRITE. Они проще всего, если физ.сектор имеет размер в 128 байт, - тогда отпадает так называемая процедура деблокирования. Потому в VDISK-ах в деблокировании нет нужды, там сразу идёт чтение лог.сектора в 128 байт на DMA. А вот для дисководов и винтов физический сектор имеет размер в 512 или 1024 байта. Тогда приходится скачивать физ.сектор в дисковый буфер, и специальной процедурой копировать из него (или в него) на DMA лог.сектор в 128 байт (хотя пересылки делаются стеком, но всё-равно тормозит). Процедуру деблокирования Вам писать не надо, только чтение/запись физического сектора.
Фирменным способом адаптация CP/M делается так (в литературе описано). По руководству от Digital Research, используя предложенный фирмой "скелетон", пишется CP/M-BIOS, в котором меняют только консольные и дисковые процедуры. После чего с помощью программы MOVCPM.COM сохраняют на диске DAT-файл CP/M настроенный на конкретные адреса BDOS и BIOS (что зависит от RAMTOP машины). Затем отладчиком встраивают в этот код свой самодельный CP/M-BIOS и затем любой программой, что позволяет читать/писать треки (обычно POWER-ом), записывают полученный блок CP/M на системные треки дискеты.
Но MOVCPM не работает с тем кодом BDOS и CCP, что был доступен в 1990 году. Может код исказился на пару байтов или ещё что. Читал, что те 6 байтов, что идут перед BDOS, в частности, использовались для идентификации конкретного кода CP/M (они также используются и CCP, для обнаружения затирания BDOS). Короче, MOVCPM нам не поможет.
Остаётся только вариант полноценно дизассемблировать CCP, BDOS и CP/M-BIOS чужой машины, изменить как надо CP/M-BIOS и затем странслировать заново под адреса уже конкретного железа. После этого, имея исходники, все дальнейшие адаптации под любое железо делаются очень легко. Потому говорить фразу "я сделал CP/M для XX-машины" неверно (это сделал Гарри Килдэлл), надо говорить "я странслировал CP/M". В качестве донора кодов использован Корвет.
В принципе мой вариант версий CP/M сложнее, чем просто странслировать базовые CCP, BDOS и BIOS, загрузить их холодным загрузчиком в ОЗУ на их адреса и сделать JMP WBOOT. Это совсем просто. Несколько усложняет мой блок стартёра, который добавляет сервис при старте и необходим, если в системе есть VDISK, который надо форматировать.
Трансляцию я делаю с использованием M80/L80 от Microsoft, т.к CP/M это модульная программа. Простой ассемблер (типа тех, что сами любители пишут для Windows), не поможет, даже если в исходнике убрать макро-команды, поменять лексику операторов из интелловской на моторолловскую и склеить все файлы в один огромный.
M80/L80 (кстати, как и большинство компиляторов ЯВУ) работают под TSR эмулятором CP/M для MSDOS, потому транслировать удобно в Windows XP, которая позволяет прогон MSDOS программ. Для более поздних Windows нужно использовать DosBox. Для трансляции нет необходимости вводить команды по одной, т.к MSDOS поддерживает BAT-файлы. Достаточно запустить вот такой BAT-файл. Т.к в CP/M компиляторы не меняют переменную окружения error level, то после каждого этапа делается остановка, чтобы глазами убедиться, что ошибок не было, иначе надо нажать ^C.
Здесь происходит сборка из 5-ти блоков, кроме стандартных CCP,BDOS,BIOS есть стартёр AUTO и драйвер VT52. Драйвера может не быть (в частности для обычного Специалиста его нет, т.к его там некуда грузить), тогда роль CONIN/CONOUT играют подпрограммы родного ПЗУ (при этом экранные CP/M-программы рассчитанные на VT52 не работают). Блока стартёра тоже может не быть, тогда надо грузить модули CCP+BDOS+BIOS на адрес CCP. Это не всегда возможно, например, ORDOS ОРИОНА не может загрузить, затирая сама себя. Потому блок снабжается стартёром и грузится максимально высоко (чтобы не затирать ОЗУ с адреса с $100, тогда после перезагрузки можно делать SAVE).
В оригинале CP/M с системных треков грузится несколько извращённо. Из-за чего порядок модулей на дискете не сплошной по адресации. Сначала там стоит CP/M-BIOS, далее CCP и BDOS. Это потому, что холодный загрузчик грузит с начальных треков дискеты лишь CP/M-BIOS и передаёт ему управление на начало, а это вход Cold Boot. После инициализации железа происходит переход на Warm Boot (WBT). По Warm Boot грузятся уже CCP и BDOS. Это несколько тормозит. Потому с 1994 я гружу с дискеты (или ещё откуда нибудь) CP/M одним сплошным блоком. Это даёт ускорение загрузки, как минимум, вдвое и преимущества.
В моих CP/M (и других DOS) добавлен блок AUTO. Это стартёр, он получает управление сразу же как только блок загрузился в ОЗУ холодным загрузчиком (с ROM-диска или с дискеты). Т.к в машине программы грузятся обычно в банку 0, то сначала, если это CP/M для другой банки, блок перекидывает себя в эту другую банку. Затем он раскидывает все модули на их рабочие адреса. В случае ОРИОНА и CP/M в банке 1, драйвер перегружается в банку 0 (где экран), а A+CCP+BDOS+BIOS перемещаются на адрес A, тем самым все блоки оказываются на своих рабочих адресах.
Затем блок стартёра сохраняет CCP+BDOS в буфере хранения, откуда в дальнейшем, они будут подкачиваться по горячему старту, и форматирует электронный диск (если ранее был установлен флаг его форматированности, то это, естественно, не делается). Если эл.диск отформатировался нормально, то он назначается диском A:, что нужно потому, что CP/M любит плеваться всякой гадостью именно на диск A:, потому если привод A: это дисковод, то дискета зазря будет изнашиваться записью при каждой загрузке и пакетном прогоне, и включить (или заклеить) защиту дискеты нельзя.
Затем стартёр делает попытку считать дискету в дисководе. Если флопа нет или не читается, то делается JMP WBOOT на горячий рестарт и происходит выход в CCP. Если же флоп читается, то там ищется файл с именем AUTOEXEC.SUB, его содержимое считывается и на диске A: (что уже м.быть эл.диск или дисковод) создаётся файл с именем $$$.SUB (т.к CCP имеет свойство запускать команды из этого файла и, пока все команды оттуда не обслужены, клавиатура не обслуживается).
Иногда (если нет ЭД с целью избежать записи на диск, т.к писать на дискету при каждой загрузке чревато быстрой дохлотой) обработка AUTOEXEC делается без $$$.SUB, т.к в моих CP/M-BIOS есть тимплет символов процедуры CONIN. Содержимое файла AUTOEXEC.SUB просто сливается туда и делается JMP WBOOT. Когда CCP начнёт работу он начнёт читать CONIN, который пока в тимлете что-то есть, будет выдавать на выход символы из тимплета один за другим (тимплет также используется, чтобы программировать функциональные клавиши, например, можно по нажатию F2 выдавать длинную команду на линковку). После получения в конце строки символа <ВК> CCP выполнит эту команду, как будто она введена с консоли (а на самом деле получена из файла AUTOEXEC.SUB) и так выполнятся все команды из файла AUTOEXEC.SUB.
В оригинальной CP/M конечно нет ни эл.дисков, ни резерва BDOS, ни обработки AUTOEXEC.SUB, ни использования RST. Большинство из этого делает добавленный крошечный модуль AUTO.ASM в 1 кб. В ранних версиях было обслуживание и файла CONFIG.SYS, это полезно, если надо одной и той же универсальной версией DOS обслуживать дисководы на 40, 35 или 80 дорожек, односторонние, двухсторонние. С 1992 это уже не надо. Если уж нужна поддержка ретро экзотики не проблема перетранслировать.
При адаптации на другую машину приходится менять модуль AUTO и модуль BIOS. Модуль AUTO в минимуме это просто LDIR - перекидыш CCP+BDOS+BIOS на адрес CCP и JMP WBOOT. А если есть эл.диск, то добавляется его форматирование. В конкретном примере CP/M Специалиста это инклюде EFORMAT.INC. Формат ЭД может быть очень медленным, когда работает функциями CP/M (это несколько секунд, что раздражает), но может быть просто заполнением банок ОЗУ кодом E5, что раз в 10 быстрее.
Для каждого лог.сектора эл.диска при его записи записывается КС (это сумма байтов с оффсетом), КС каждого сектора можно писать сразу после сектора (тогда секторный шаг 129 и сектора примыкают с разрывом в один байт), но лучше писать КС в отдельном буфере контрольных сумм (тогда файлы в ОЗУ в исходном виде). Оффсет подобран так, что КС сектора заполненного Е5 также равен Е5, потому заливка всего ОЗУ кодом Е5 эквивалентна медленному посекторному форматированию.
Т.к адаптация состоит в принципе из двух частей - из модификации CP/M-BIOS и из изготовления подрограмм записи/чтения сектора реальных физических устройств, то обычно я начинаю с отладки консольных процедур BIOS и общей работы CP/M (для машины с одной банкой это не так уж полезно, а вот когда CP/M для машины с банками и хитрым диспетчером памяти, лучше отлаживать по частям).
Для отладки общей работы модулей CP/M не нужен ни дисковод, ни большой эл.диск из доп.ОЗУ. Под эл.диск используем обычное основное ОЗУ. Можно отвести под VDISK сколько-то килобайт под RAMTOP, а CP/M загрузить ниже.
Конкретнее на примере Специалиста-Экспресс. У него есть сплошные 35.75 кб ниже 9000 и ещё "открытое ОЗУ" в 10 кб в адресах D000...F7FF. С целью отладки CP/M, отдаём 9 кб в окне D000...F7FF под эл.диск из ОЗУ (это в принципе то же основное ОЗУ). Но можно было выделить под ЭД и традиционное ОЗУ в адресах 6F00...8EFF, опустив RAMTOP для CP/M на 8 кб.
Из 9-ти килобайт один килобайт отнимет каталог, значит VDISK будет иметь полезный объём 8 кб. Этого хватит даже чтобы запустить DDT и ZSID. Эл.диск нам нужен не для использования, он просто должен быть, чтобы CP/M стартанУла (без диска она не может), так что можно отвести на VDISK всего 2 кб и даже стартануть совсем без него (тогда READ должна всегда читать сектор состоящий из E5). Цель такой версии лишь убедиться, что блоки правильно грузятся и консольные и простые дисковые подпрограммы BIOS работают. Берем файл VDISK.INC и изменяем его так, чтобы сектора хранились в основном ОЗУ с D000.
В этом драйвере VDISK-а всего 4 подпрограммы: записать сектор EDIWR, считать сектор EDIRD и вспомогательные подпрограммы CMPADR, рассчитывающая по TRACK и SECTOR адрес хранения сектора в ОЗУ D000, служащим эл.диском и ADRCHS рассчитывающая адрес, где хранится КС текущего (записываемого/читаемого) логического сектора (в области PLCCHS в банке BNKCHS).
Параметры эл.диска видны: 8 секторов по 128 байт на треке, т.е в каждом треке 1024 байта. ETRK это число треков по 1К, что умещается в ОЗУ D000...F7FF. EDSIZE это размер диска в блоках (размер блока выбран 1К, это 8 лог.секторов). Всё что требуется при модификациях под конкретный диск (неважно ЭД или дискетный) это подставить числа, остальное из параметров CP/M ассемблер сам рассчитает. PLCCHS и BNKCHS это адрес и номер банки, где хранятся контрольные суммы секторов (обычно это в других банках, но здесь только банка 0). В данном случае число секторов 72 и они все умещаются с адреса 8F00 в основной банке 0.
Сделав таким образом VDISK.INC уже можно было бы странслировать CCP+BDOS+BIOS. Но VDISK при старте CP/M нуждается в форматировании. Потому CP/M с VDISK-ом не обойдётся без модуля A.ASM. В нём нам надо изменить только процедуру формата, которая целиком в инклюде файле EFORMAT.INC.
Обратите внимание на подмену векторов ошибок BDOS, это надо чтобы в случае ошибки BDOS, не вываливаться в CCP (как бывает в программах дилетантов в случае дисковых ошибок). Перед выходом из процедуры форматирования VDISK-а вектора ошибок BDOS восстанавливаются. Видно, что перед форматированием делается попытка читать с эл.диска. Если это удаётся, то проверяется, что тип эл.диска (VDTYPE) тот же самый, что поддерживает данная версия. Это надо, когда версий DOS много.
Code: Select all
ADRTYP EQU 8F00H + (ETRK * EPARM) ; это за концом блока КС
BNKTYP EQU 0
VDTYPE EQU ETRK
Эта версия конечно, не для работы, а просто стартовая. В ней далее надо заняться увеличением TPA (подняв код CP/M в верхнее ОЗУ) и увеличить VDISK используя банки. Вот пара скриншотов работы этой стартовой версии в эмуляторе EMU80 (с доработанным конфигом): при загрузке формат VDISK-а, загрузка с МГ-ленты.
Т.к ПЗУ Специалиста, не обрабатывает даже минимальный набор искейп-команд, то как видите, ввиду отстутствия драйвера, пришлось их эмулировать. Для чего на входе CONOUT отлавливается код 27. Этот эмулируемый набор искейп-кодов позволяет пользоваться текстовым редактором WM.COM. Есть даже коды для аппаратных роликов, что резко ускоряет текстовые редакторы. Из подпрограмм ПЗУ Специалиста используются только C803, С809 и C81B.
В этой версии использующей под VDISK только основное ОЗУ, под буфер хранения CCP+BDOS использовано $1600 байтов с адреса $7510. В итоге, в этой версии для TPA остаётся менее 24 кб.
Во всех моих DOS (не только CP/M) есть RST-входы. Содержимое файла RST.INC по горячему старту кидается на адрес 0008. Потому RST в CP/M доступны всегда, хотя некоторые отладчики портят RST 30 (но по WBOOT всё восстанавливается). Чаще всего используются функция RST 18. Это аналог MSSG C818, но текст располагается сразу за командой RST и останов не только по 0, но и по символу с выставленным старшим битом (в некоторых моторолловских ассемблерах есть оператор похожий на DEFB, но выставляющий старший бит у последнего символа). А с М80, чтобы выставить старший бит последнего символа приходится писать 'буква' OR 80H. Такой вывод экономит байты, (экономия в 5 байтов на каждом вызове), а данная конкретная версия (со стопом по биту D7=1) не позволяет КОИ-8 (но это и не надо для системных сообщений, тем и фонта КОИ-8 нет).
Т.к в специалистовском ПЗУ вывод лишь в КОИ-7, а для CP/M нужны и мелкие латинские буквы, то добавлена загрузка мелких латинских букв (на 8B00, а выше дисковый буфер 512 байт для РК-КНГМД). Чтобы не грузить заглавные латинские буквы, раз уж они и без того есть в ПЗУ (экономия $200 байтов), драйвер CONOUT при получении символа с кодом выше $60 переставляет адрес фонта (8FE5, он там делённый на 8 ) на загруженный в ОЗУ фонт мелких латинских букв. Естественно, чтобы не тратить объём в BIOS, перекидыш фонта (LFONT.INC) на 8B00 делает стартёр, а не сам BIOS.
Теперь о добавленных в CP/M-BIOS подпрограммах. Они добавляются в мои DOS с 1994. Подпрограмма DSKNEW BIOS+33 нужна для машин у которых не один формат дискеты, а много. Эта подпрограмма вызывается ф-цией BDOS дисковый RESET. DSKNEW настраивает BIOS на формат текущего диска. BIOS+36 и BIOS+39 это RRAM и WRAM, аналоги п/п-рамм ОРИОНА предназначеные для доступа в ОЗУ других банок. Именно этими подпрограммами (и только через них) организуется VDISK. BIOS+3C это DSKNAM, возвращает имя дискеты, для чего читаются 11 байтов из BOOT-сектора. И BIOS+3F это ERRSND противный звук выводимый при ошибках.
Отладив CP/M с таким простейшим VDISK-ом из основного ОЗУ, т.е работу VDISK-а и консольные функции, далее уже совсем просто перетранслировать CP/M с размещением CCP+BDOS+BIOS в верхнем ОЗУ в области D000...F7FF и VDISK-ом уже не из основного ОЗУ, а из ОЗУ других банок.
Получится CP/M почти такая же как использовалась на Специалистах в начале 90-тых (тогда естественно были только дискетные приводы, VDISK-а не было). Я это (версию с доп.банками) отладил не в реале, а в эмуляторе EMU80, куда его автор Pyk любезно добавил другие банки ОЗУ по 62 кб (как в Специалист-MX), но коммутиремые как в ОРИОНЕ по OUT F9.
Не обязательно транслировать CP/M с VDISK-ом, можно упростить BIOS и стартёр, выкинуть VDISK и использовать дискетные подпрограммы для РК-КНГМД. Для этого достаточно закомментировать include VDISK.INC и отредактировать п/п-мму SELDSK. Тогда единственным приводом (A:) будет дисковод с РК-КНГМД, а эл.диска совсем не будет.
Но в любом случае для любых интересантов будут полезны готовые исходники CCP, BDOS и рабочий BIOS Специалиста, все без Z80-команд. Здесь CCP почти оригинал (добавлена лишь команда CLS). Для Z80 у меня есть улучшенные CCP. В принципе, как пример для трансляции лучше использовать более простой вариант (без эл.диска, AUTOEXEC-а, с упрощённым BIOS), чисто дискетную версию. Может сделаю. Есть кстати и CP/M для РК86, но она тоже с эл.диском.
По ссылке можно скачать исходник этой стартовой версии CP/M для Специалиста с VDISK-ом в 9 кб (из основного ОЗУ) и TPA в ~24 кб (работает с любым ПЗУ C000). Чтобы получить RKS-файл CP/M достаточно запустить BAT-файл, компилятор в папке уже есть. Если не Win XP, то под DosBox.
В папку по ссылке также добавил исходник копировщика файлов на одном дисководе, - этого мне очень не хватало в 1990/91, приходилось копировать POWER-ом (загружаем файл с 4000 по LOAD, затем меняем диск, ^C и SAVE под тем же именем). К сожалению, т.к POWER сам здоровый в ~16 кб, а TPA в базовом Специалисте всего 35.5 кб, то с ним мне удавалось копировать файлы размером лишь до 20 кб (позднее я использовал ZSID3, который имел размер всего в 9.5 кб, что позволяло с его помощью копировать файлы аж в 26 кб). Для копирования файлов весной 1991 мне пришлось купить второй дисковод 5311. А первый копировщик файлов на одном дисководе появился лишь в самом конце 1991.
Кстати и вторая версия CP/M тоже промежуточная, использовалась для тестирования работы эмулятора с поддержкой других банок. VDISK в 32 кб в ней потому что, сначала в эмуляторе была сделана коммутация банок лишь до 8000. После это было исправлено и была странслирована версия с VDISK-ом в 500 кб (препятствий для 2 мб тоже не было). Но недавно у меня винт сдох и многое утратилось или не под рукой (в архивных носителях).
Я уже позабыл как конфигурировать EMU80, чтобы были доп.банки ОЗУ, а эмулятора и старых конфигов для этого уже нет. Забыл даже назначение бита D7 порта F9. "Открыть ОЗУ" D000...F7FF я смогу, а вот сходу разобраться как сделать доп.банки вряд-ли быстро смогу. Надо читать переписку с автором. Вообще, всем нужно иметь собственные эмуляторы, чтобы не зависеть...
UPD. Версию EMU80 с поддержкой банок всё-же удалось найти на архивном CD-RW (правда пока не знаю окончательная ли это версия банковости с окном в 62 кб или предшествующая, лишь с окном в 48 кб). Так что вскоре, наверное, странслирую CP/M Специалиста с эл.диском в ~400 кб, а может быть даже оригинал CP/M Специалиста из 1990 года с КНГМД на ВГ93 (но это можно прогнать только в EMU). И может быть также чисто для примера скомпоную простой классический вариант CP/M из 3-х модулей.
https://yadi.sk/d/nNdjSuS1V8ZVeA