Октябрь 2019
ПнВтСрЧтПтСбВс
 123456
78910111213
14151617181920
21222324252627
28293031   

Календарь Календарь

Последние темы
» Новинки. Книги. Часть 1.
автор Viktor2312 Сегодня в 09:55

» Упрощаем схему Микро-80 и исправляем косяки. И собираем по технологиям 80-х годов.
автор Microsha Вчера в 23:02

» AVR AY плеер
автор Microsha Вчера в 17:55

» Микроконтроллеры STM32G0
автор Viktor2312 Вчера в 14:38

» SINOVATE (SIN). Криптовалюта Синовэйт.
автор Viktor2312 Вчера в 12:10

» Новости криптовалют: статьи, заметки, разное...
автор Viktor2312 Вчера в 09:11

» Усилитель на 6ф5п
автор freddy Ср Окт 16 2019, 16:07

» "Python". Статьи, заметки, очерки, разное...
автор Viktor2312 Вт Окт 15 2019, 21:18

» Анти Радио-86РК
автор freddy Вт Окт 15 2019, 16:38

» Конверсия atx бп
автор freddy Вт Окт 15 2019, 15:48

» Источники питания. Статьи, заметки, очерки, разное...
автор Viktor2312 Вт Окт 15 2019, 04:08

» Радио-86РК: внешние видео-адаптеры
автор freddy Вс Окт 13 2019, 19:28

» Изучаем основы VHDL, ISE, ПЛИС Xilinx.
автор Viktor2312 Сб Окт 12 2019, 11:20

» Электроника. Статьи, заметки, очерки, разное...
автор Viktor2312 Пт Окт 11 2019, 13:00

» Радио-86РК: Разное
автор barsik Чт Окт 10 2019, 15:36

» Общие вопросы по ПЭВМ Ириша
автор barsik Вс Окт 06 2019, 07:01

» ПО. ПЭВМ "Ириша". Текстовый редактор "WORDSTAR".
автор barsik Сб Окт 05 2019, 18:28

» Расширение ОЗУ в ИРИШЕ
автор Viktor2312 Пт Окт 04 2019, 17:27

» Радио РК-86: ПЭВМ с процессором 1821ВМ85
автор Viktor2312 Пт Окт 04 2019, 12:28

» Другой микропроцессор в ИРИШЕ
автор barsik Чт Окт 03 2019, 18:16

» Флейм касающийся ПЭВМ "Ириша".
автор barsik Чт Окт 03 2019, 07:31

» Модуль контроллера графического дисплея (МКГД).
автор Viktor2312 Ср Окт 02 2019, 00:50

» Новости. Xilinx.
автор Viktor2312 Вт Окт 01 2019, 12:07

» ПО. ПЭВМ "Ириша". Текстовый редактор "ИРИТЕКСТ".
автор Viktor2312 Сб Сен 28 2019, 00:34

» Криптовалюта — словарь терминов и определений.
автор Viktor2312 Пт Сен 27 2019, 23:00

Самые активные пользователи за месяц
Viktor2312
ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Vote_lcapПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Voting_barПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Vote_rcap 
barsik
ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Vote_lcapПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Voting_barПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Vote_rcap 
freddy
ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Vote_lcapПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Voting_barПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Vote_rcap 
Microsha
ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Vote_lcapПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Voting_barПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Vote_rcap 
leoperetz
ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Vote_lcapПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Voting_barПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Vote_rcap 

Поиск
 
 

Результаты :
 


Rechercher Расширенный поиск


ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M.

Перейти вниз

ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Empty ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M.

Сообщение  barsik в Чт Авг 08 2019, 07:31

1
Язык PL/M, который был изобретён кем-то в 1972 году (для написания программ в кодах процессора Intel 4004) и широко применяемый на заре цивилизации (в 70-тые годы) для программирования микропроцессоров (и особенно микроконтроллеров) считается самым эффективным ЯВУ.

PL/M для небольших программ даёт коэффициент разбухания объёма кода относительно аналогичной программы написанной на ассемблере - в пределах 1.3...1.5. Т.е аналог ассемблерной программы написанный на PL/M будет иметь объём кода всего в 1.5 раза больше и будет прогоняться во столько же раз медленнее. Для сравнения, аналог ассемблерной программы написанный на Си или Паскале будет, как минимум, в 4-5 раз больше и во столько же тормознее. Причём и трудозатраты при программировании на PL/M сокращаются (т.к в исходнике меньше букв и затраты времени на отладку намного меньше).

Естественно, это речь об оптимально написанной программе на ассемблере. Но писать на ассемблере очень утомительно и долго и, естественно, даже опытные программисты не всё делают оптимально. Потому для больших программ (особенно для программ со сложным алгоритмом) иногда оказывается, что программа написанная на PL/M получается меньше по размеру, чем аналог написанный на ассемблере.

Хотя это не значит, что как компилятор PL/M эффективнее, а значит лишь, что программист не очень старался. Кстати, в литературе на ассемблере рекомендуют программировать в стиле "quick and dirty", - важнее написать программу быстрее, пусть и далеко не оптимально. Потому, что срок жизни программы мал, а время программиста очень дорого.

Кроме того использование ЯВУ облегчает работу со сложными алгоритмами, программа более понятна, легче найти ошибки. Замена ассемблера на даже самый примитивный ЯВУ исключает ошибки, которые характерны и легко совершаются на ассемблере. Что позволяет с'экономить много времени на отладке и поиске ошибок.

_________________
***
barsik
barsik
Мастер++

Сообщения : 573
Дата регистрации : 2016-11-10

Вернуться к началу Перейти вниз

ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Empty .

Сообщение  barsik в Чт Авг 08 2019, 09:21

2
С другой стороны, если посчитать, что PL/M это очень крутой и удобный для программиста язык, то удивляет почему он не получил широкого распространения в любительском программировании. В Интернете в качестве примеров для изучения можно скачать несколько сотен исходников любительских программ на бейсиках, Паскалях и Си, но буквально единицы программ на PL/M. Да и то, что можно найти, это в основном CP/M (версий 1.0, 1.3 и 1.4), утилиты для неё (которые конечно были написаны не любителями, а Гарри Килдэлом и его женой) и игра CHESS (которая при ближайшем рассмотрении оказалась вовсе не на PL/M, а на похожем по синтаксису языке PL/I).

Возможно это объясняется с одной стороны недоступностью любителям компилятора PL/M, а с другой стороны, возможно его неэффективностью как удобного инструмента программиста (несмотря на его эффективность кодогенерации). Ведь PL/M близок к машинному языку и поэтому, возможно, менее значительно облегчает программирование, чем более развитые алгоритмические языки. Это можно узнать лишь написав несколько программ с объёмом кода в 10-12 кб, что я и попробую сделать.

PL/M в западном мире в своё время (т.е в 70-тые годы XX века) в основном использовался в виде кросс-средства на майн-фрейме (т.е мощном коллективном компьютере). Например, Гарри Килдэл использовал свой компилятор на популярном дековском майн-фрейме PDP-10.

А из микро-ЭВМ, похоже, PL/M-80 был доступен тогда только на микрокомпьютерах фирмы Intel, в частности на MDS-800 (это прототип отечественной СМ-1800), где был его компилятор для ОС ISIS. Но т.к ОС ISIS труднее переносится на другие компьютеры, то она так, похоже, и осталась ОС для одного компьютера (да и, вероятно, если и была возможность, никто лицензию на её использование в других ЭВМ покупать не хотел, т.к была доступна недорогая CP/M, для которой было большее число программ и её инсталляция для любой ЭВМ не проблема).

Любители программирования в 70-тые годы вряд ли имели компьютеры с ОС ISIS или покупали маш.время майн-фреймов подключенных по модему со скоростью 300 бод. Да и дисководы были в 70-тые годы ещё слишком дороги и малодоступны малообеспеченным слоям пролетариата. По этим причинам, предположительно, любители и не имели доступа к компилятору PL/M-80.

Видимо, когда с начала 80-тых стали доступны дисководы, дающие возможность поиметь DOS, то PL/M стал, во-первых, уже неактуален, т.к появились более удобные и мощные ЯВУ. Любители бытовых 8-ми разрядок использовали лишь ассемблер и бейсик; с дисководом к ним добавились классические Си и Паскаль. А во-вторых, возможно любители просто не имели версии компилятора PL/M для CP/M. По крайней мере пока, версию компилятора PL/M-80 работающую в ОС CP/M никто не смог найти. Для CP/M-86 и MSDOS компиляторы и кросс-компиляторы PL/M есть, а для CP/M-80 почему-то нет. Т.е этот компилятор или был слишком мало распространён и утерялся, или его просто не было. Вот здесь http://www.retrotechnology.com/dri/dri_plm.html даже нет упоминания об этом.

Хороших (да по сути любых) учебников по PL/M я найти не сумел, хотя для покупки в виде бумажного носителя или для скачки за оплату они в Интернете есть. Возможно это не столь печально, т.к насколько я понимаю, методы программирования на PL/M должны быть те же, что и на ассемблере. Возможно потому в единственном учебнике, который мне удалось скачать, в основном изложено описание языка из интелловского руководства по PL/M. Есть небольшие примеры не особо много дающие. Вот здесь скачивается эта книжка , там и про другие ЯВУ есть книги. Вероятно никакой учебник и не нужен, если есть небольшой опыт программирования на ассемблере для CP/M.

Сейчас PL/M-исходник можно скомпилировать в коды процессора КР580 тремя инструментами. Во-первых, в эмуляторе ОС ISIS для MSDOS. Понятно, что этот компилятор не имеет поддержки чуждой ОС CP/M (т.е для трансляции программ не для ISIS нужно добавить свою библиотеку ввода/вывода) и потому имеет смысл лишь для программ на КР580 работающих без DOS. Т.е процедуры ввода/вывода в программе должны быть свои, а не из самого компилятора или библиотеки функций ОС ISIS.

Во-вторых, в XXI-м веке были открыты исходники PL/M-80 на Фортране-IV (вероятно они от фирмы Intel) и для MSDOS был странслирован кросс-компилятор. Он довольно странный и не очень удобный в использовании. Но некоторые люди разобрались как им пользоваться и успешно применили его даже для написания игр. Тут достоинство в том, что это оригинал, потому все имеющиеся исходники должны компилироваться без проблем.

И третий вариант, это найденный Эммануэлем Роше (Emmanuel ROCHE) в 2009 году компилятор PLMX для CP/M, который был написан в 1979 г. человеком по имени Roger Carlson. Компилятор PLMX, это похоже, чуть улучшенный вариант PL/M-80, причём он есть в версии как раз для ОС CP/M. Он тоже не однофайловый, состоит, как и PL/M для ISIS, из более, чем десятка файлов с общим размером порядка 100 кб.

На выходе PLMX генерит текст на ассемблере. Оригинал выдаёт файл с расширением MAC (но это расширение можно изменить на ASM, заменив в стартовом файле байты с оффсетом $13A). Но этот полученный на выходе компилятора текстовый файл предназначен вовсе не для трансляции ассемблером MAC.COM от Digital Research, т.к он годится только для одномодульных программ. А так как к программе на PL/M обязательно должны подключаться библиотеки (как минимум, библиотека времени исполнения RLIB), то для трансляции годятся только системы ассемблирования с использованием компоновки и перемещаемых REL-модулей.

Потому полученный на выходе PLMX ассемблерный текст следует транслировать только с помощью (relocatable) ассемблеров RMAC или M80, которые на выходе выдают REL-файл. После чего все REL-файлы полученные при трансляции модулей программы, библиотека ввода/вывода PLMX (IOLIB) и RUN TIME библиотека (RLIB) линкуются в единый COM-файл линковщиком.

Таким образом PL/M-программа всегда состоит из нескольких модулей, которые могут быть написаны не только на PL/M или на ассемблере, но также и на других ЯВУ (у которых их компилятор выдаёт на выходе совместимый с ассемблером RMAC.COM формат REL-файла).

Т.к недавно я поимел для ИРИШИ CP/M, то уже в ближайшие годы собираюсь освоить программирование для ИРИШИ на PL/M используя именно этот компилятор PLMX. К сожалению, оказалось, что на реальной 8-ми разрядке в CP/M или в эмуляторе 8-ми разрядки с CP/M трансляция длится слишком долго. Даже простенькие программки типа 'Hello World' дающие на выходе всего 200 байт кода компилируются полминуты. Похоже, что программа на 10 кб будет компилироваться на реальной 8-ми разрядке более 10 минут.

Под тем TSR эмулятором CP/M для MSDOS, которым я пользуюсь, PLMX почему-то не работает, зависает. Потому транслировать приходится или на реале или в полноценном CP/M-эмуляторе (т.е в эмуляторе, где вызовы CP/M не заменяются на эквиваленты MSDOS, а прогоняется код самой CP/M). Чтобы не набирать вручную всякий раз команды трансляции и линковки, удобно написать SUB-файл.

http://www.retrotechnology.com/dri/kildall_highlevel_1974.pdf


Последний раз редактировалось: barsik (Пт Сен 20 2019, 20:39), всего редактировалось 6 раз(а) (Обоснование : исправление опечаток и дополнение ссылками)

_________________
***
barsik
barsik
Мастер++

Сообщения : 573
Дата регистрации : 2016-11-10

Вернуться к началу Перейти вниз

ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Empty .

Сообщение  barsik в Пт Авг 09 2019, 15:54

3
По той ссылке на гитхаб автор дизассемблировал в исходник на PL/M cаму DOS ISIS (она оказывается, как и ранние CP/M, была написана на PL/M) и версии PL/M версий 2, 3 и 4 от Intel для ОС ISIS (видимо эти компиляторы для 8-ми разрядки были написаны не на фортране, а на самом PL/M). О написании ISIS и PL/M для неё можно почитать здесь: http://www.retrotechnology.com/dri/isis.html.

Затем автор конвертировал PL/M-исходники в Си-исходники, видимо так ему удобнее их модифицировать (для работы в другой ОС), чтобы странслировать для других DOS. А возможно и с целью сделать улучшенную версию кросс-компилятора PL/M-80 для Windows.

Для получения кросс-средства на PC и для программиста постоянно программирующего на Си - это конечно удобно, но для компиляции в код 8-ми разрядки такой трюк невыгоден, т.к Си даёт в разы менее плотный код. Для кросс-компилятора на PC это не важно, там ОЗУ как грязи, но если найдётся какой-нибудь специалист по Си, то он сможет странслировать эти исходники компилятора PL/M на Си и для CP/M.

Видимо, если разобраться в том, что предлагает данный автор с гитхаба, то на PC возникнет ещё один (может быть даже хороший) кросс-инструмент для программирования на PL/M для КР580.

Ссылки на гитхаб, никогда не интересны. Что толку от исходников, если ты не профессиональный программист и не используешь именно применённый автором инструментарий. На гитхаб я уже давно перестал заходить, это просто бесполезная трата времени. Даже, если поймёшь, что скачать, то странслировать всё-равно не сумеешь.

А первая ссылка содержит компилятор PL/M исходно полученный путём трансляции оригинальных исходников на фортране (возможно тем же автором с гитхаба, т.к там тоже сначала конвертировали фортран-исходник в Си-исходник) и снабжённый препроцессором на базе "lua". Это как-раз дистрибутив kakos-nonos-а с приложенным примером игры написанной на PL/M.

Но как раз в вышеприведённой цитате, взятой с другого форума, я и писал, что это уже получается не классический PL/M, а искажённый. Т.к kakos-nonos, видимо для экономии текстонабора, убрал точки с запятой, что в PL/M (да и в большинстве других ЯВУ) завершают оператор, - точки с запятой добавляет препроцессор, отчего на строке д.быть только один оператор. Из-за этого этот инструмент вообще не транслирует нормальные PL/M-программы (чтобы странслировать классические исходники нужна программка убирающая точку с запятой в конце строк). Возможно это удобнее, когда привыкнешь, но в начале освоения, когда пытаешься использовать имеющиеся примеры и читаешь учебники, это сбивает с толку.

Да и скорее всего диагностика ошибок в древней версии слабее. А главное, использование TASM заставляет писать куски на ассемблере в мнемониках КР580. Использование PLMX конечно тоже не лишено проблем, но он по крайней мере традиционен и использует для трансляции нормальный инструментарий (M80/L80).

Было бы больше пользы, если бы вы выложили "PL/M-80 Programming Manual" не в оригинальном виде на иностранном языке, а переведённым на русский язык. Английский оригинал любой и сам может скачать из Интернета. Нужны те документы, что трудно скачать или найти или перевести на русский или они платные.

Кстати, хотя этот документ тоже полезен, т.к это видимо окончательный стандарт PL/M-80, и вероятно PLMX сделан по нему. Но вообще-то это описание относится к версии для ОС ISIS, тогда как версия для MSDOS получена из оригинального исходника на Фортране-IV, написанного Гарри Килдэлом для PDP-10. Вероятно потому, что для ISIS тоже не было компилятора Фортрана-IV, компилятор PL/M работающий на 8-ми разрядке пришлось написать на самом PL/M.

Конечно описания в основном совпадут, но видимо более правильное описание версии для MSDOS - вот это, более древнее.


Последний раз редактировалось: barsik (Вс Авг 11 2019, 07:58), всего редактировалось 2 раз(а) (Обоснование : дополнял ссылками)

_________________
***
barsik
barsik
Мастер++

Сообщения : 573
Дата регистрации : 2016-11-10

Вернуться к началу Перейти вниз

ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Empty Re: ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M.

Сообщение  barsik в Пт Авг 09 2019, 16:36

4
Viktor2312 пишет:По части переводов, это уже вам делать
Речь шла о машинном переводе. Кстати, именно этот текст можно перевести, т.к он получен из текста, а не из графики. Я не люблю английский и соответственно не люблю читать на английском, т.к он слишком неконкретный и плох для технических текстов. А с тех пор, как научился переводить сайты, то, если на англоязычном сайте нужно читать много текста, то быстрее и главное удобнее получается, если потратить пару минут для перевода сайта на русский, - на русском читать и быстрее и приятнее.

Чтобы читать без словаря и вполне понимать технические тексты, газеты и лёгкую беллетристику, достаточно выучить всего 10...15 тысяч основных слов. Их нетрудно заучить всего за 2-3 месяца, если тратить по 2 часа каждый день. Выучивать по 150 слов в день в состоянии любой (грамотная система запоминания это облегчает).

Но без закрепления это забудется очень быстро. Потому важно, как только выучил эти 10.000 слов, сразу же прочитать хотя бы 50 книг не заглядывая в словарь - это займёт год и расширит словарный запас до 100.000 слов. Иначе вообще всё изучение и все усилия будут впустую. Точнее, есть два пути - или за год прочитать эти 50 книг или поехать на полгода в чужую страну и погрузиться в среду чужого языка.

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

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



Последний раз редактировалось: barsik (Сб Авг 24 2019, 12:40), всего редактировалось 1 раз(а)

_________________
***
barsik
barsik
Мастер++

Сообщения : 573
Дата регистрации : 2016-11-10

Вернуться к началу Перейти вниз

ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Empty .

Сообщение  barsik в Пт Авг 09 2019, 18:01

5
Viktor2312 пишет:хотелось бы увидеть по итогу результат, программу компилятора для базовой ИРИШИ
Это уже есть, любой из имеющихся компиляторов годится для написания программ для ИРИШИ. Причём PLMX для CP/M можно использовать для трансляции даже на самой ИРИШЕ с CP/M и вообще для любого компьютера на КР580. Кстати для Z80, похоже, компилятора PL/M не сохранилось.
Viktor2312 пишет:что-то ещё, желательно с нормальным описанием
Всё понятно уже описано в документации к PLMX (это тоже на английском, но TXT файл переводится без проблем).

Чтобы запустить компилятор на трансляцию из исходника на PL/M в исходник на ассемблере пишешь строку:

A> PLMX MYPROG<ВК>

Если ошибки настолько серъёзны, что происходит аборт без создания выходного файла (со списком ошибок), то помогает запуск с выводом листинга на экран:

A> PLMX MYPROG ; L+C+<ВК>

Так можно обнаружить с какой строки начинаются ошибки. Но листинг большой программы выводится долго. После окончания трансляции на диске возникает файл MYPROG.MAC. Это текст на ассемблере. Теперь его надо странслировать в исполняемый код компилятором ассемблера. Для этого запускаем компилятор ассемблера М80:

A> M80 =MYPROG<ВК>

Если M80 по умолчанию использует расширение MAC, то расширение MAC можно не указывать. Расширение исходного файла по умолчанию в М80 можно изменить изменяя 3 байта в коде файла M80.COM с отступом 6 от начала (я у себя изменил расширение по умолчанию в PLMX и в M80 на ASM, теперь оба они по умолчанию используют это расширение, я привык к расширению ASM). Если ошибок нет, тогда появится сообщение "No Fatal error(s)" и на текущем диске появится файл MYPROG.REL.

Далее нужно к коду программы на PL/M прилинковвать процедуры ввода/вывода и нужные процедуры из RUN-тайм библиотеки, т.к сам PL/M не включает в себе эти функции (это чтобы компилятором можно было компилировать программы для любой платформы). Для линковки с использованием стандартных (т.е включённых в дистрибутив) функций CP/M вводим команду:

A> LINK MYPROG, IOLIB[S], RLIB[S]<ВК>

Для программ работающих без CP/M, т.е запускаемых, например, в среде монитора (РК86, ИРИШИ или других) требуется прилинковывать свою библиотеку ввода/вывода. Но RUN-тайм библиотеку всегда надо прилинковывать стандартную.

A> LINK MYPROG, IRAIO[S], RLIB[S]<ВК>

Как и указано в сопроводительном файле, в библиотеке RLIB есть нефатальная ошибка (возможно сознательная), двойное определение одной метки. Т.е одна процедура BP67@ при компоновке включена в библиотеку дважды. Это препятствует включению целиком всей библиотеки в программу (это происходит, когда не указан ключ [S]), - тогда возникает ошибка двойное определение метки.

Но включать всю библиотеку в программу и не надо. С ключом [S] из REL или LIB файла извлекаются только нужные подпрограммы (для RLIB это обычно 100...400 байт). А библитека RLIB прилинкованная целиком без всякой пользы увеличивает объём кода на ~4 кб. IOLIB не содержит двойных меток и её можно прилинковывать целиком, но в этом тоже нет смысла, впустую увеличивать объём кода на 7 кб, потому ключ [S] не стоит забывать.

После отработки линковщика на диске появляется файл MYPROG.COM. Обратите внимание, что трансляция делается М80, а вот линковка делается не линковщиком L80 из пакета M80, а линковщиком LINK от Digital Research. L80 транслирует с ошибками. Кажется так надо из-за того, что IOLIB и RLIB.REL - в формате библиотекаря Digital Research. Для L80, кстати, другая командная строка: L80 P, IOLIB/S, RLIB/S, P/N/E (ключ /S означает, что файл библиотека). Отличие модуля от библиотеки в том, что модуль в код включается целиком, а из библиотеки берутся только использованные в данной программе процедуры.

В ДОК-файле к PLMX указано, что для интерфейса с ОС CP/M надо использовать библиотеку ввода/вывода IOLIB.REL. В файле IOCLD.SRC перечислены CP/M-процедуры, что включены в эту библиотеку. Узнать какие там есть процедуры и какие у них внешние ссылки можно с помощью библиотекаря LIB или LIB80. Библиотекари тоже в двух видах от Digital Research и от Microsoft (это не считая библиотекарей предназначенных для конкретных ЯВУ из их дистрибутивов, у них обычно другой REL-формат). Эти два библитекаря немного отличаются по форматам, по использованию и ключами. Но делают одно и то же.

Для написания программ для CP/M достаточно библиотеки IOLIB. Для программ под ИРИШУ я использую свой модуль ввода/вывода. Для начала в этот модуль включил вывод символа на экран, опрос статуса, ввод с клавиатуры, вывод байта в HEX-виде, вывод дампа, ввод командной строки, управление видео режимами ИРИШИ. Для изучения PL/M этого достаточно.

Для запуска странслированной программы вводим команду MYPROG<ВК> и проверяем как работает. Для многоблочных программ ком.строка для линковки чуть длиннее (в ней перечисляются все модули). Это всё, что надо знать про пользование компилятором.

PLMX сам у меня, похоже, не работает под TSR эмулятором CP/M (а M80/L80, BDS Си, Паскаль MT+ работают). Потому пока транслирую в эмуляторе ОРИОНА с CP/M. Всё-равно удобнее проверять в эмуляторе ОРИОНА, а не в эмуляторе ИРИШИ. Но даже для небольших программ ~1 кб (при эффективном такте CPU в 5 МГЦ) приходится долго ждать результата трансляции.

Потому я использую свой эмулятор ОРИОНА, который позволяет оперативно переключать скорость эмулятора на максимум (EMU и EMU80 такой возможности не имеют). Хотя это тоже неудобно (только сама трансляция делается в Турбо, а ввести команду в CCP при этом невозможно, - приходится снова включать нормальную скорость прогона в 5 МГЦ), но всё же не надо ждать конца трансляции многие минуты, при установке константы торможения 0 - трансляция длится одну секунду.

Т.о, чтобы программировать на PL/M достаточно выучить сам язык PL/M (т.е, как минимум, полностью изучить "PL/M Programming Manual" и почитать книги) и, если надо делать программу работающую с файлами на диске, то ещё надо немного знать и работу функций BDOS CP/M (т.е в этом случае ещё надо почитать документацию по CP/M).

Диагностика ошибок хуже, чем в Паскале МТ+, а из-за медленности трансляции в эмуляторе скорость разработки, скорее всего, окажется ниже, чем на Паскале (тем более, что Паскаль МТ+ может транслировать под TSR эмулятором, т.е быстро).

Вот в этой статье указано, что в фирме Intel затрата времени на разработку программ на PL/M оказывалась в 5 раз короче, чем при разработке на ассемблере. Но у меня пока получилось писать программы на PL/M не в 5 раз быстрее, чем на ассемблере, а наоборот, - в 5 раз медленнее, чем на ассемблере.

- - - Добавлено - - -

barsik пишет:для Z80, похоже, компилятора PL/M не сохранилось
Компилятор PL/M под Z80 возможно ещё можно отыскать, т.к вот здесь написано, что Z80-компилятор PL/M 30 лет назад существовал.

Впрочем, т.к в КР580-компиляторе PLMX используется не прямая трансляция в объектный код, а создаётся программа на ассемблере, то мы можем даже в созданном компилятором PL/M тексте вручную (или машинно) откорректировать хотя бы некоторые JMP-ы (там где программный переход в пределах +/- 127 ) заменив их на JR (предварительно конвертировав полученный исходник в мнемонику Z80). Обычно такая замена позволяет сократить объём кода (и ускорить прогон) на 3-5 процентов (особенно, если постараться и переставлять короткие фрагменты текста так, чтобы как можно больше JR получилось).

При этом в SUB-файл добавится ещё одна строка - запуск программы конвертирующей исходник в мнемоники Z80 (замену JP на JR, естественно, надо делать не в ходе отладки, а только для окончательной последней трансляции ради экономии объёма кода).

Хотя ручная конверсия в JR в большой программе может сильно утомить. Потому замену JP на JR желательно автоматизировать - можно написать (на любом ЯВУ) умную программу обработки ассемблерных текстов в мнемонике Z80, которая будет для каждого JMP-а проверять возможность замены на JR и, если это возможно, делать такую замену автоматически.

Удивительно, что в развитые ассемблеры до сих не встроили такое свойство. Или в текстовые редакторы не встроили команду считающую число байтов между текущей строкой и меткой стоящей в этой строке в ассемблерном тексте для процессоров Z80/6800/8086.

А если поискать в коде КР580 загрузки регистровых пар BC и DE из ОЗУ (это цепочка команд заменяющая Z80-команды LD RR,(nnnn) ), которые легко найти по близко стоящим двум командам EX DE,HL (т.к загрузка делается через HL), то можно заменить это на одну Z80 команду загрузки регистровой пары. Кстати, в коде от ЯВУ довольно много таких загрузок.

Ну, а благодаря использованию М80, который в отличие от TASM позволяет в одном исходнике иметь мнемоники и КР580 и Z80 и 6502, библиотеки процедур ввода/вывода и все модули написанные на ассемблере можно писать прямо в командах Z80, используя все его дополнительные команды.

Стандартные (т.е дистрибутивные) библиотеки: библиотеку ввода/вывода IOLIB и RUN-тайм библиотеку RLIB.REL тоже можно конвертировать в коды Z80. Для этого надо из REL-файла получить объектный код, дизассемблировать его, затем в полученном исходнике расставить метки в соответствии с именами меток в оригинальном REL-файле. После чего можно в этом исходнике сделать коррекции под Z80, а затем вновь странслировал в REL-файл. Хотя особого смысла в этом нет, т.к PL/M даёт вполне компактный код и нет смысла делать доп.усилия, чтобы его сократить ещё больше.

PLMX не транслирует исходники-примеры на PL/M, что можно найти в Интернете. Потому что они все написаны под оригинальный компилятор от Гарри Килдэла (т.е от фирмы Intel). Программа для компилятора PLMX отличается хотя бы тем, что она должна быть оформлена в виде блока:

ProgName: DO;
текст программы
END ProgName;.

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

В исходниках на PL/M предназначенных для компиляции с помощью PLMX возможна инклюдэ-вставка. Это делается (причём обязательно с первой позиции строки) такой строкой:

$ include (IOHEADER)

Где в скобках - имя файла имеющего на диске расширение .SRC. Из-за медленной компиляции в эмуляторе не имеет особого смысла оформлять в виде инклюдэ-файлов строки самой программы (наоборот, выгоднее сокращать модули). Но для вставки в основную программу заголовков библиотечных процедур, не генерирующих кода, - это удобно (в PL/M используемые в данном модуле процедуры и данные из другого модуля должны быть предварительно описаны, причём с атрибутом 'external').

Однако, почему-то, если странслировать с помощью PLMX один модуль имеющий инклюдэ вставку, а затем из SUB-файла транслировать второй с тем же инклюдэ, то возникает ошибка открытия файла. Это странно и совершенно непонятно, как будто файл не закрывается, а флаг открытия не очищается. Непонятно как такое может быть, ведь выход из PLMX делается на Warm Boot, что равнозначно ^C, что сбрасывает дисковую систему, закрывает все файлы и даже закачивает BDOS заново. С учётом этого явления надо для каждого модуля иметь свой инклюдэ с описаниями внешних процедур и данных. Это не напрягает.

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

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

Вот в этой статье указано, что в фирме Intel затрата времени на разработку программ на PL/M оказывалась в 5 раз короче, чем при разработке на ассемблере.

Первые впечатления от компилятора хорошие, хотя при написании на PL/M первых простых программ получилась затрата времени не в 5 раз меньше, чем на ассемблере, а наоборот, - в 5 раз больше. Частично это из-за низкой скорости трансляции и потому, что пока не запомнил все нюансы, делал кучу синтаксических ошибок, которые приходилось искать, на что из-за дурной диагностики и медленной перетрансляции уходило много времени.

Надеюсь, что вскоре, привыкнув и накопив опыт, смогу писать программы на PL/M почти также быстро, как на бейсике. Да и по сути отличия от бейсика только в отсутствии развитых операторов работающих со строками и чисел с плавающей запятой. Зато, как написано в рекламе, PL/M-программа работает в 20 раз быстрее. При нужде кое-какую обработку строчных переменных несложно написать в виде своих процедур на PL/M.

Создаёт некоторое неудобство, что PLMX использует в идентификаторах только 5 символов. А все CP/M-ассемблеры используют 6 символов для адресных меток. Например, из-за этого внешнюю процедуру на ассемблере нельзя назвать GETLIN, можно только GETLN. Сам язык PL/M тоже не очень удобный, особенно раздражает применение CALL - для встроенных операторов его не надо, а для процедур надо использовать. Для процедур работающих в качестве функций CALL тоже не пишется.

Уже возникли сомнения, что PL/M даёт очень компактный код, хотя логику и арифметику на нём делать явно на порядок проще, чем на ассемблере. Хотя похоже, что даже немного попрограммировав на этом ЯВУ, программист уже не захочет всё делать на ассемблере. Здесь удачно также, что объединение с ассемблерными участками кода - без всяких хлопот.

Для PLMX математическая библиотека и арифметика с плавающией точкой не входила в дистрибутив и должна была быть куплена пользователем отдельно. А сам этот дистрибутив компилятора PL/M, судя по рекламе, стОил в 1980 году аж $1000. Для сравнения, если МНИП, CP/M продавалась за $45, пакет M80/L80 - $180, другие компиляторы ЯВУ стоили не более $300. Возможно, причиной помешавшей стать этому компилятору более популярным стала именно высокая цена, неподьёмная для любителей 8-ми разрядок. Хотя я согласен с тем, что написал Эммануэль Роше, что этот компилятор в 1980 году справедливо стоил таких денег.

Т.о, пока из-за отстутствия библиотеки с плавающей точкой на этом компиляторе не удастся написать расчёт траектории полета на Марс или программу для банковских расчётов. Потому удачно, что это мне пока не требуется. Из математики для 8-ми разрядки полезна лишь функция расчёта синусов, т.к она нужна при начертании кругов. Но для ИРИШИ даже это не актуально, т.к у неё в ROM-BIOS уже есть п/п-мма для рисования кругов. Да и в принципе библиотеку для целочисленных расчётов с увеличенной точностью (например, для 24-х битовых чисел) с 4-мя основными арифметическими действиями несложно добавить.

Кстати, в книге Ангермейера "ОС CP/M" про PL/M ни слова, а про PL/I как раз написано, что "многие программисты считают, что PL/I это самое удобное средство для разработки ОС, трансляторов с ЯВУ и системных утилит". Т.е тоже, что считается и про PL/M. Возможно это потому, что компилятор PL/I продавала известная фирма Digital Research, а PL/M безвестная фирма, состоящая из одного программиста.

Чтобы полностью оценить компилятор и сам язык PL/M недостаточно написать десяток простейших ознакомительных программ. Потому, чтобы освоить программирование на PL/M собираюсь попробовать в ближайшие дни написать несколько простых программ покрупнее, с объёмом в 3-4 кб (надеюсь, что это займёт не более 10-15 часов).

Пока самые крупные программы, что я странслировал на PLMX, это программки имеющие объём кода до 2 кб, причём в них основная программа всего в несколько строк, почти весь объём это подпрограммы или процедуры. Пока загрузку/запись файлов делаю даже не на PL/M, а на ассемблере (взяты готовые подпрограммы написанные 25 лет назад). Использовать библиотечные дисковые CP/M-процедуры ещё не пытался, т.к использование своего и уже готового не тратит время.

Библиотечные консольные и дисковые CP/M-процедуры вполне работают, хотя для простых программ достаточно своих аналогичных функций. В принципе даже писать свои процедуры на ассемблере излишне, то же самое написанное на PL/M работает ненамного хуже. Использовать ассемблерные процедуры имеет смысл только, если они уже были написаны на ассемблере ранее или для случая, что надо сокращать объём кода.

Кстати, лишь имея всего две функции "загрузить файл целиком и записать файл из ОЗУ", можно не особо напрягаясь сделать много разных полезных мелких программ типа конверторов. При наличии процедур загрузки/сохранения файла, остаётся написать только саму процедуру конверсии (текстов или других данных).

- - - Добавлено - - -

В начале освоения программирования на ЯВУ помогает, если смотреть синтаксис операторов в других уже отлаженных программах. Потому, чтобы Вам было легче начать программировать с помощью компилятора PLMX, приведу несколько примеров простейших учебных программок.

Вот пример простейшей одномодульной учебной программы на PL/M. В ней не используется своих ассемблерных процедур. Для ввода/вывода используются процедуры WR$CON и RD$CON для ввода и вывода с консоли из стандартной библиотеки IOLIB. Остальные нужные процедуры вывода написаны на самом PL/M. Эта крошечная программка демонстрирует работу стандартных процедур NUMIN и NMOUT для работы с числами.

Первая процедура NUMIN берёт на входе строку HEX-цифр в ASCII и конвертирует её в 16-ти разрядное число, а вторая процедура NMOUT получает на входе 16-ти разрядное число и выводит в строчный буфер в виде соответствующих ASCII-цифр. Причём можно задать основание чисел от 2 до 16, например, стандартные (HEX, DEC, OCT, BIN, с основанием 16, 10, 8, 2) или даже задать нестандартное основание счисления, например 6 или 7.

Это в данной библиотеке такой способ вывести на экран десятичное или шестнадцатиричное число. Сначала выводим его в буфер в виде ASCII-текста, затем в этот буфер выводим стоп байт (0 или '$'), а потом программой вывода строк выводим его на экран. Интересно узнать получается ли с этими стандартными процедурами для вывода HEX/DES чисел объём кода меньше.

В ассемблере я привык это делать проще - двумя подпрограммами выводящими числа как 16-ти ричные или 10-ти ричные. Потому я написал для удобства свои процедуры для вывода HEX-числа и числа в десятичном виде. Причём похоже, реализация процедуры PRDES для вывода в виде десятичного 24-х битового числа, что была когда-то написана мной на ассемблере при написании нортона, будет в разы меньше по объёму кода, чем аналог написанный на PL/M. Потому что даже PRDES для вывода всего лишь 16-ти разрядного числа с выравниванием (по левому или правому краю, что задаёт в данной процедуре флаг FLAG)  уже занимает так много места, что вся эта программа заняла почти 2 кб. А для 24-х разрядного числа код будет намного больше (т.к я не знаю как в PL/M работать с числам более 16-ти разрядными).

В этой программе сначала заранее заданная ASCII-строка конвертируется в число, а затем оно печатается в HEX-виде и десятичном виде с помощью своих функций. А затем тоже делается с помощью стандартной процедуры NMOUT и процедуры печати строки. Из этого видно, что удобнее делать вывод 16-ти ричных чисел процедурами HEX и WORD, десятичных чисел процедурами DES и PRDES.

работа с числами в PL/M:

P: DO;
        DECLARE ASCII (5) BYTE DATA ('3456',0);
        DECLARE (DD,UK) ADDRESS;
        DECLARE DIGBUF (6) BYTE INITIAL ('$$$$$$');

        DECLARE COUT LITERALLY 'WR$CON';
        DECLARE CONIN LITERALLY 'RD$CON';

/* --------------------------------------------------- */

WR$CON: PROCEDURE (CHAR) EXTERNAL;
          DECLARE CHAR BYTE;
        END WR$CON;

/* --------------------------------------------------- */

RD$CON: PROCEDURE BYTE EXTERNAL;
        END RD$CON;

/* --------------------------------------------------- */

/* ASCII number to 16-bit binary */

NUMIN:  PROCEDURE (DIGBUF) ADDRESS EXTERNAL;
          DECLARE  DIGBUF  ADDRESS;
        END NUMIN;

/* --------------------------------------------------- */

/* вывод числа в буфер в виде ASCII-цифр (HEX,OCT,DES и др) */

NMOUT:  PROCEDURE (VALUE, BASE, LC, BUFFADR, WIDTH) EXTERNAL;
          DECLARE (VALUE, BUFFADR) ADDRESS;
          DECLARE (BASE, LC, WIDTH) BYTE;
        END NMOUT;

/* --------------------------------------------------- */

NIBLE:  PROCEDURE (CH);
          DECLARE CH BYTE;
          IF (CH:=CH AND 00001111B)<10 THEN CALL COUT(CH+'0');
          ELSE CALL COUT(CH-10+'A');
        END NIBLE;
       
/* --------------------------------------------------- */

HEX:    PROCEDURE(BYT);
          DECLARE BYT BYTE;
          CALL NIBLE(ROR(BYT,4));       CALL NIBLE(BYT);
        END;

/* --------------------------------------------------- */

WORD:   PROCEDURE (ADR);
          DECLARE ADR ADDRESS;
          CALL HEX(HIGH(ADR)); CALL HEX(LOW(ADR));
        END WORD;
       
/* --------------------------------------------------- */

SPACE:  PROCEDURE;
          CALL COUT(32);
        END SPACE;

/* --------------------------------------------------- */

MSSG:   PROCEDURE (UK);
          DECLARE UK ADDRESS, A BASED UK BYTE;
          DO WHILE (A<>0) AND (A<>'$');
             CALL COUT(A AND 7FH);
             IF A>127 THEN RETURN;
             UK=UK+1;
          END;
        END MSSG;
       
/* --------------------------------------------------- */

CR:     PROCEDURE;
          DECLARE TCR (2) BYTE DATA (13,10+128);
          CALL MSSG(.TCR);
        END CR;

/* --------------------------------------------------- */

DES:    PROCEDURE (BYT);
          DECLARE BYT BYTE;
          IF BYT>99 THEN DO; CALL MSSG(.('??$')); RETURN; END;
          CALL NIBLE(BYT/10); CALL NIBLE(BYT MOD 10);
        END DES;
       
/* --------------------------------------------------- */

PRDES:  PROCEDURE (ADR,FLAG);
          DECLARE ADR ADDRESS, (FLAG,BB,FF) BYTE;

SPC:    PROCEDURE;
          IF FLAG<>0 THEN CALL SPACE;
        END SPC;
         
          FF=0;
          IF (BB:=LOW(ADR/10000))=0 THEN CALL SPC;
            ELSE DO; FF=255; CALL NIBLE(BB); END;
          ADR= ADR MOD 10000;
          IF ((BB:=ADR/100)>9) OR (FF<>0) THEN CALL DES(ADR/100);
            ELSE IF BB=0 THEN DO; CALL SPC; CALL SPC; END;
                 ELSE DO; CALL SPC; CALL NIBLE(BB); FF=255; END;
          IF ((BB:=ADR MOD 100)>9) OR (FF<>0) THEN CALL DES(BB);
              ELSE DO; CALL SPC; CALL NIBLE(BB); END;
        END PRDES;

/*--------- MAIN PROG ----------*/

        UK = .ASCII; DD=NUMIN(.UK);
        CALL WORD(DD); CALL SPACE; CALL PRDES(DD,0); CALL CR;

        CALL NMOUT(DD,16,' ',.DIGBUF,4); CALL MSSG(.DIGBUF);
        CALL SPACE;
        CALL NMOUT(DD,10,' ',.DIGBUF,5); CALL MSSG(.DIGBUF);
END P;


Т.к в этой программе для вывода используются процедуры ввода/вывода WR$CON и RD$CON из стандартной библиотеки, то линковать надо с библиотекой IOLIB, вот так:

A> LINK P, IOLIB[S], RLIB[S] ).

А вот пример многомодульной программы. Здесь кроме основного модуля P.SRC используется модуль D.SRC с процедурой вывода дампа (обратите внимание, что процедуры в нём доступные извне объявлены как PUBLIC) и ассемблерный модуль IO.ASM, содержащий основные мелкие подпрограммы ввода вывода на ассемблере (потому стандартный IOLIB не требуется). Их надо странслировать и слинковать командой:

A> LINK P, IO, D, RLIB[S]<ВК>

основная программа:

P: DO;
        DECLARE TITR (20) BYTE DATA (13,10,'DUMP DEMO:',13,10,0);
       
DUMP:   PROCEDURE (UK,LINES) EXTERNAL;
        DECLARE UK ADDRESS, LINES BYTE;
        END DUMP;

MSSG:   PROCEDURE (ADR) EXTERNAL;
        DECLARE ADR ADDRESS;
        END MSSG;

        CALL MSSG(.TITR);
        CALL DUMP(100H,16);
END P;

модуль IO на ассемблере:

      .Z80
        cseg
       
        public  HEX, COUT, CONIN, MSSG, XF81B
        public   CHSUM, CR, WORD, SPACE, NSPC
       
; ---------------------------------------------------

LOOP    MACRO   ADDR
        DEC     BC
        LD      A,B
        OR      C
        JP      NZ,ADDR
        ENDM

; ---------------------------------------------------

.emit   MACRO   PARM
        LD      A,PARM
        CALL    SCOUTA
        ENDM
       
; ---------------------------------------------------

XF81B:  JP      0F81BH

; ---------------------------------------------------

CHSUM:  LD      H,B
        LD      L,C
        CALL    0F82AH
        LD      H,B
        LD      L,C
        RET    

; ---------------------------------------------------

SPACE:  LD      C,20H
COUT:   LD      E,C
        LD      C,2
        JP      5
       
; ---------------------------------------------------

CONIN:  LD      C,1
        JP      5
       
; ---------------------------------------------------

MSSG:   LD      H,B
        LD      L,C
MSGLOO: LD      A,(HL)
        OR      A
        RET     Z
        RET     M
        CP      '$'
        RET     Z
        CALL    SCOUTA
        INC     HL
        JP      MSGLOO

; ---------------------------------------------------

CR:     LD      A,13
        CALL    SCOUTA
        LD      A,10
        JP      SCOUTA
       
; ---------------------------------------------------

HEX:    LD      A,C
HEX_A:  PUSH    AF
        RRCA
        RRCA
        RRCA
        RRCA
        CALL    NIBBLE
        POP     AF
NIBBLE: AND     0FH
        CP      10
        CCF
        ADC     A,30H
        DAA
SCOUTA:
        PUSH    HL
        PUSH    DE
        PUSH    BC
        LD      E,A
        LD      C,2
        CALL    5
POPREG: POP     BC
        POP     DE
        POP     HL
        RET
       
; ---------------------------------------------------

WORD:   LD      A,B
        CALL    HEX_A
        LD      A,C
        CALL    HEX_A
        LD      A,32
        JP      SCOUTA

; ---------------------------------------------------

NSPC:   LD      B,C
SPCLOO:
        .emit   20H
        DEC     B
        JP      NZ,SPCLOO
        RET

        END

модуль D:

D: DO;

COUT:   PROCEDURE (CHAR) EXTERNAL;
        DECLARE CHAR BYTE;
        END COUT;
       
MSSG:   PROCEDURE (ADR) EXTERNAL;
        DECLARE ADR ADDRESS;
        END MSSG;
       
NSPC:   PROCEDURE (BYT) EXTERNAL;
        DECLARE BYT BYTE;
        END NSPC;

GETLN:  PROCEDURE (ADR) BYTE EXTERNAL;
        DECLARE ADR ADDRESS;
        END GETLN;
       
WORD:   PROCEDURE (ADR) EXTERNAL;
        DECLARE ADR ADDRESS;
        END WORD;

CONIN:  PROCEDURE BYTE EXTERNAL;
        END CONIN;
       
HEX:    PROCEDURE (CHAR) EXTERNAL;
        DECLARE CHAR BYTE;
        END HEX;

CR:     PROCEDURE EXTERNAL;
        END CR;
       
SPACE:  PROCEDURE EXTERNAL;
        END SPACE;
       
/*--------------------------------------------*/

HEXBL:  PROCEDURE (CHAR) PUBLIC;
        DECLARE CHAR BYTE;
        CALL HEX(CHAR); CALL SPACE;
        END HEXBL;
       
DUMP:   PROCEDURE (UK,LINES) PUBLIC;
        DECLARE UK ADDRESS, LINES BYTE, A BASED UK BYTE;        
        DECLARE TMP ADDRESS, (I,J,OST,SKP) BYTE;

ASCII:  PROCEDURE (CHAR);
        DECLARE CHAR BYTE;
        IF CHAR>128 THEN CHAR='.';ELSE;
        IF CHAR<32 THEN CALL COUT('.');
        ELSE CALL COUT(CHAR);
        END ASCII;
       
WORD2:  PROCEDURE (ADR);
        DECLARE ADR ADDRESS;
        CALL CR; CALL WORD(ADR); CALL SPACE;
        END WORD2;

        IF LINES=0 THEN DO; CALL WORD(UK); CALL HEX(A); RETURN; END;
           
        DO WHILE LINES<>0;
        CALL WORD2(UK); SKP=UK AND 7;
       
        IF SKP<>0 THEN
          DO;
            CALL NSPC(SKP*3);
            OST=8-SKP; TMP=UK;
            DO J=1 TO OST;
               CALL HEXBL(A); UK=UK+1;
            END;
           
            UK=TMP;
            CALL NSPC(2+SKP);
            DO J=1 TO OST;
               CALL ASCII(A); UK=UK+1;
            END;
          END;

        ELSE
          DO;
            TMP=UK;
            DO J=1 TO 8;
              CALL HEXBL(A); UK=UK+1;
            END;
           
            UK=TMP; CALL NSPC(2);      
            DO J=1 TO 8;
              CALL ASCII(A); UK=UK+1;
            END;
          END; /* IF */
         
            LINES=LINES-1;
        END;

        END DUMP;

END D;

Для многих программ типа конверторов или даже редакторов (например редакторов фонтов или даже неогромных текстов) достаточно иметь загрузку/сохранение файлов целиком. При этом я использую очень давно написанные готовые процедуры на ассемблере, которые в разы короче, чем аналоги написанные на PL/M. Вот ассемблерный модуль для работы с файлами, что я использую в программах типа редактора фонтов, редактора текстов и других программах несложной текстообработки. Для использования достаточно включить в основную программу предописание этих процедур и при линковке прилинковывать этот отдельно странслированный модуль LDSV.ASM, например так:

A> LINK PROG, IO, LDSV, RLIB[S]

ассемблерный модуль LDSV.ASM:

       .Z80
        cseg

        PUBLIC  LOAD, SAVE, FCB1, FCB2, NSECT

; ------------------------------------------------

fconin  EQU     1
fcout   EQU     2
fmssg   EQU     9
frdbuf  EQU     10
fstatus EQU     11
freset  EQU     13
ferase  EQU     19
fopen   EQU     15
fseldsk EQU     14
fclose  EQU     16
ffirst  EQU     17
fnext   EQU     18
flread  EQU     20
flwrite EQU     21
fmake   EQU     22
frenam  EQU     23
faskdsk EQU     25
fsetdma EQU     26
fuser   EQU     32

; ------------------------------------------------

; Дисководные модули LOAD и SAVE

; Загрузка файла FCB1 по адресу (BC) до адреса (DE)

LOAD:   LD      H,B
        LD      L,C
        LD      (BUFADR),HL
        EX      DE,HL
        LD      (TOPADR),HL

        CALL    OPN1
        JP      NZ,LOAD1
        XOR     A               ; CY=0
        LD      A,1
        RET

; ------------------------------------------------

LOAD1:  LD      HL,000
        LD      (NSECT),HL
        LD      HL,(BUFADR)
LDLOOP: PUSH    HL
        LD      (BUFADR),HL     ; конец блока при выходе
        EX      DE,HL
        CALL    SETDMA
        CALL    LRD1
        POP     HL              ; при выходе
        JP      NZ,LDDONE
        PUSH    HL
        LD      HL,(NSECT)
        INC     HL
        LD      (NSECT),HL      ; число считанных секторов
        POP     HL
        LD      DE,80H
        ADD     HL,DE

        EX      DE,HL
        LD      HL,(TOPADR)     ; контроль на MEMTOP
        EX      DE,HL

        LD      A,L             ; сравнение HL-DE
        SUB     E               ; CY=1, если DE>HL
        LD      A,H
        SBC     A,D

        JP      C,LDLOOP
        LD      A,2
        RET

; ------------------------------------------------

LDDONE: DEC     A
        JP      Z,LOAD3
        XOR     A
        LD      A,3
        RET

; ------------------------------------------------

LOAD3:  LD      DE,FCB1
        CALL    CLOSE
        INC     A
        JP      Z,SAVERR
        CALL    DMA80
        LD      HL,(NSECT)
        SCF                     ; возврат, всё O'KAY, CY=1
        RET

; ------------------------------------------------

SAVE:   ; файла FCB2, длиной DE секторов, с адреса BC

        LD      H,B
        LD      L,C
        LD      (BUFADR),HL
        EX      DE,HL
        LD      (NSECT),HL

        LD      HL,000
        LD      (FCB2+20H),HL
        LD      (FCB2+21H),HL
        LD      DE,FCB2         ; DE - FCB
        PUSH    DE
        CALL    ERASE
        POP     DE
        LD      C,FMAKE
        CALL    SBDOS
        JP      Z,SAVERR

        LD      HL,(BUFADR)
        EX      DE,HL           ; LD DE,адрес блока
        LD      HL,(NSECT)      ; LD HL,число секторов
SAVLOP: LD      A,H
        OR      L
        JP      Z,SAVDONE
        DEC     HL              ; счётчик оставшихся секторов
        PUSH    HL
        LD      HL,80H
        ADD     HL,DE           ; DE - указ.DMA
        PUSH    HL
        CALL    SETDMA          ; адрес DMA в DE
        LD      DE,FCB2
        LD      C,FLWRITE
        CALL    5
        OR      A
        POP     DE              ; в DE - адрес DMA
        POP     HL              ; в HL - кол.сект.
        JP      Z,SAVLOP
SAVERR: CALL    DMA80
        XOR     A
        RET                     ; возврат с CY=0, рег.A=0

; ------------------------------------------------

SAVDONE:
        CALL    CLOS2           ; готово
        INC     A
        JP      Z,SAVERR
        CALL    DMA80
        SCF                     ; возврат, всё O'KAY, CY=1
        RET

; ------------------------------------------------

CLOS2:  LD      DE,FCB2
CLOSE:  LD      C,FCLOSE
SBDOS:  CALL    5
        LD      (FLGBDS),A
        INC     A
        RET

; ------------------------------------------------

OPN1:   LD      DE,FCB1
OPEN:   LD      C,FOPEN
        JP      SBDOS

; ------------------------------------------------


;FIRST:  LD     DE,FCB1
;        LD     C,FFIRST
;        JP     SBDOS

; ------------------------------------------------

ERASE:  LD      C,FERASE
        JP      5

; ------------------------------------------------

LRD1:   LD      DE,FCB1
READ:   LD      C,FLREAD
        CALL    5
        OR      A
        RET

; ------------------------------------------------

;ASKDSK: LD      C,FASKDSK
;        JP      5

; ------------------------------------------------

DMA80:  LD      DE,0080H
SETDMA: LD      C,FSETDMA
        JP      5

; ------------------------------------------------


;USER:   LD     C,FUSER
;        JP     5

; ------------------------------------------------


;SELDSK: LD     E,A
;        LD     C,FSELDSK
;        JP     5

; ------------------------------------------------

NSECT:  DW      00001           ; счётчик секторов
BUFADR: DW      100H
TOPADR: DW      0C400H

FLGBDS: DS      1

; ------------------------------------------------

FCB1:   defb    0,'FONT    '    ; для чтения
        defb    'DAT'
        DS      37-9-3
       
FCB2:   defb    0,'NEWFONT '    ; для записи
        defb    'DAT'
        DS      37-9-3

        END


Данные процедуры LOAD и SAVE грузят/сохраняют файл целиком, т.е позволяют работать с файлами имеющими размер TPA минус размер программы. При размере программы в 4-6 кб это около 50 кб, чего достаточно, например при использовании в текстовом редакторе, даже для текстов довольно сложных программ. Ну а для редактора фонтов (где размер фонта обычно 2048, а максимум - 2560 байтов) ничего другого и не надо. При подключении этого модуля в основной программе вставляется вот такое предописание этих процедур:

        DECLARE FCB1 ADDRESS EXTERNAL;
        DECLARE FCB2 ADDRESS EXTERNAL;

SAVE:   PROCEDURE (ADR,NSECT) EXTERNAL;
        DECLARE (ADR,NSECT) ADDRESS;
        END SAVE;

LOAD:   PROCEDURE (BUF,TOP) ADDRESS EXTERNAL;
        DECLARE (BUF,TOP) ADDRESS;
        END LOAD;

Здесь в процедуре SAVE её параметрами задаётся адрес начала блока для записи и число лог.секторов (по 128 байт), которое требуется записать в файл. Имя файла подготавливается в FCB2. А при чтении файла заданного FCB1 входными параметрами процедуры LOAD задаётся адрес DMA (куда грузить) и адрес вершины ОЗУ (до куда можно грузить), а возвращается число считанных секторов.

Обратите внимание, что в этих ассемблерных подпрограммах в качестве флага успешности используется флаг CY (сarry из регистра флагов CPU), код ошибки возвращается в рег.А. Удобно, что в PL/M, в отличие от других ЯВУ, можно использовать флаги самого процессора как параметры возвращаемые из процедур. Для анализа успешности надо проверять встроенную переменную CARRY оператором следующим сразу за вызовом процедуры. Флаги процессора можно использовать также для передачи в процедуру не имеющую передаваемых параметров. В данном случае сразу после вызова процедур LOAD или SAVE вставляем строчку обработчика ошибок:

IF CARRY=0 THEN CALL ERROR(nn);

Процедура ERROR - без возврата, т.е это не подпрограмма. В простейшем виде она просто ставит курсор на последнюю строку, выводит код ошибки и делает выход в CP/M по RST 0. Но не проблема сделать полноценный анализ ошибки и исправление с возвратом на main_loop программы. Процедуру ERROR даже в упрощенном виде удобно иметь, чтобы использовать для целей отладки.

Кстати, любая CP/M-программа работающая с диском должна делать обработку всех четырёх дисковых ошибок BDOS, иначе такая программа является "детским лепетом" (хотя программы именно с таким недостатком писали для ОРИОНА программисты-любители, не знающие нюансов CP/M, т.к не дизассемблировали и не изучали  BDOS и даже не дизассемблировали в познавательных целях фирменных программ). Программа без обработки дисковых ошибок по первой же ошибке (например ошибка "диск R/O" или дохлота сектора) вылетает на Warm Boot по ^C после вывода на экран сообщения "BDOS ERROR ...".

Простейший блок обслуживания дисковых ошибок для программ на PL/M я покажу чуть позже (он очень простой). Но хорошо его можно сделать только для конкретной машины с конкретным качественным драйвером вывода (пусть чисто текстовым, но желательно оконным). Тогда, например, по дохлоте диска не будет вылета по ^C с потерей всех данных, а будет выведено окно с сообщением об ошибке и ошибка будет исправлена.

- - - Добавлено - - -

Т.к я недавно странслировал на PL/M несколько несложных программ с выходным кодом в 2-3 кб, могу сделать некоторые предварительные выводы. Главный вывод, - компилятор PLMX работающий в реале в среде CP/M очень тормозной.

Если равноценная программа написанная на ассемблере компилируется и линкуется в реале с помощью M80/L80 за примерно 20 секунд, то компиляция и линковка аналогичной программы написанной на PL/M (~300 строк) занимает более 10-ти минут. И это при работе на электронный диск, с дисководом будет ещё медленнее. А более сложная программа с числом строк не в несколько сотен, а в несколько тысяч строк предположительно будет транслироваться целый час.

Конечно, 10 и более минут ждать при каждой модификации кода утомительно. Потому я транслирую в эмуляторе, где можно поставить скорость Z80 в ~50 МГЦ. Это ускоряет, но всё-равно на одну итерацию (модификация-проверка) уходит примерно минута. Чтобы сократить время уходящее на цикл модификация-проверка, разумно все уже отлаженные процедуры перемещать из основной программы в другой модуль, уже не перетранслируемый всякий раз при модификациях основной программы.

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

И резкого ускорения процесса разработки программ на ЯВУ, по крайней мере для меня, не случилось. На написание одной программы на бейсике я потратил менее 4 часов, на написание того же на ассемблере у меня ушло бы не более двух часов, а написание этой программы на PL/M мне понадобилось более 20 часов, причём даже с качеством хуже, чем на бейсике или ассемблере.

Конечно программа на PL/M получается намного более организованной и структурированной и со временем я смогу писать программы на PL/M быстрее, чем на ассемблере. Писать, но не транслировать! До тех пор пока не будет быстрого кросс-компилятора.

Для трансляции ассемблерных исходников в MSDOS (под TSR эмулятором CP/M) пригодны M80/L80, благодаря чему на трансляцию и линковку тратится всего две секунды (и те не на собственно трансляцию и линковку, а на чтобы прочитать сообщение "No Fatal errors" и нажать пробел или закрыть окно MSDOS в противном случае). А для PL/M такого кросс-компилятора работающего со скоростями PC нет, - надо тратить целых 10 минут на трансляцию, потому пока разработка на ассемблере оказывается намного эффективнее. Компиляторы Паскаля и Си тоже работают под резидентным CP/M-эмулятором 22NICE, потому разработка программ на этих ЯВУ тоже оказывается быстрее и к тому же легче и удобнее.

Т.о, чтобы компиляция PL/M-программ делалась быстро, надо искать полноценный эмулятор CP/M работающий в Windows, в котором можно использовать компилятор PLMX или надо переходить к использованию оригинального компилятора PL/M перетранслированного для MSDOS.

PLMX действительно является немного расширенным относительно PL/M от Гарри Килдэла, т.к есть некоторые встроенные процедуры, которых нет в оригинале. Например, для написания динамичных игр, а также и для борьбы с дребезгом клавиш (при использовании для их опроса вызова ПЗУ по CALL 0F81BH) очень удобна процедура TIME(), которая даёт задержку на 1 МСЕК (на ОРИОНЕ - на 0.2 МСЕК, так что, чтобы получилась задержка на 1 секунду пишем CALL TIME(5000); . Внешние библиотечные процедуры, естественно, уже не относятся собственно к компилятору, хотя точно также расширяют возможности компилятора.


Последний раз редактировалось: barsik (Пн Авг 26 2019, 11:58), всего редактировалось 9 раз(а) (Обоснование : дополнил, убрал грамматические ошибки и добавил новые)

_________________
***
barsik
barsik
Мастер++

Сообщения : 573
Дата регистрации : 2016-11-10

Вернуться к началу Перейти вниз

ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Empty .

Сообщение  barsik в Сб Авг 24 2019, 12:43

6
Интересно, что встречал в старых иностранных обзорах мнение, что в связи с отсутствием "железа" нужного для работы кросс-компилятора PL/M-80 (т.е майн-фреймов из начала 70-тых), сейчас этот язык, как и аналогичный язык MPL для процессора 6800 - уже недоступны. Что лишний раз подтверждает отсутствие компилятора PL/M-80 для ОС CP/M-80.

PL/M, естественно, удобнее для разработки, чем ассемблер, особенно, если он даёт код хотя бы вдвое более компактный, чем Паскаль или Си. Хотя синтаксис у него на мой взгляд менее удобный, относительно даже Паскаля. А на Си, тем более, сложные условные выражения разбирать легче. Пока у меня складывается впечатление, что по сравнению с ассемблером PLMX даёт объём кода, как минимум, в два раза больший, а не лишь на 25% больший. Дополнительные потери относительно ассемблера вызывает передача/возврат в/из процедур байтовых параметров 16-ти битовым словом.

Некоторые свойства PL/M в компиляторе PLMX не работают (или м.б работают как-то иначе). Разобраться можно только экспериментально, т.к сопроводительный текст в дистрибутиве компилятора не описывает все нюансы, а более полной документации нет (той на которую есть ссылки в сопроводительном файле).

В частности, оператор GOTO не работает как в оригинальном компиляторе от Intel, - почему-то не получается сделать переходы 'GOTO переменная' и 'GOTO константа' (работает только оператор 'GOTO label'). Можно сделать лишь CALL на внешнюю процедуру (но CALL это вовсе не JMP). Думаю, что в данном компиляторе свобода переходов признана ненужной и опасной и потому исключена. Это правильно, потому, что считается, что строгость языка позволяет сократить число ошибок при разработке.

Но из-за этого, чтобы адаптировать некоторые оригинальные примеры, где для интерфейса с CP/M используется оператор GOTO 5, мне пришлось на ассемблере написать процедуру JMP5, которая очищает стек возврата процессорной командой POP, а затем выполняет процессорную команду JMP 5. Когда команда GOTO 5 стоит последней в процедуре, то выгоднее заменять такой GOTO на CALL ADR5 объявив ADR5 внешней процедурой (что не приводит к потерям в объёме кода, тогда как при сбросе стека тратятся 4 байта). Кстати, бессмысленно ставить GOTO 5 в конце процедуры, надеясь на экономию за счёт исключения кода RET, т.к компилятор, даже если последний оператор процедуры GOTO, всё-равно вставляет RET в конце процедуры.

Совместимость с оригинальными PL/M-программами также нарушает отличие по меткам. Все метки в программе для PLMX, что стоят после оператора GOTO на них должны быть объявлены, причём (в отличие от оригального PL/M) метку в PLMX даже нельзя объявить EXTERNAL. А в программах для оригинального компилятора PL/M метки почему-то (вопреки требования мануала) вообще не объявляют, даже когда они стоят после GOTO, и для меток допустим атрибут EXTERNAL.

Вообще отличий от компилятора Гарри Килдэла много. Потому все примеры программ для оригинального PL/M от Гарри Килдэлла не работают и нуждаются в существенной адаптации.

В PLMX не поддерживаются структуры, двумерные массивы, нет MEMORY, нет реентерабельности процедур, есть и другие упрощения относительно оригинала PL/M от Гарри Килделла. Т.о PLMX это не улучшенный вариант PL/M, а по некоторым возможностям даже упрощённый. А некоторые добавленные операторы, описанные в документации (например MOVE) вообще не работают, дают 'system error at XXXX'.

В приложенном в дистрибутив описании есть ссылки на "PL/M-80 manual" от Intel, т.е ясно, что автор использовал стандарт языка от оригинального компилятора. Но непонятно описание какого года выпуска. Их много - 1975, 1977, 1978 и 1980. В раннем описании PL/M-80 из 1975 года ещё нет оператора STRUCTURE и нет дескриптора AT. А в более поздних описаниях оба они уже есть (и кстати, оператор STRUCTURE введён не в PL/M-86, как пишет Э.Пройдаков, а намного раньше, - он есть и в версиях PL/M-80 для ОС ISIS). Т.к в PLMX структур нет, то можно думать, что автор руководствовался стандартом 1975 года. Но нет, т.к оператор AT в стандарте 1975 года отсутствовал, а в PLMX он есть. Так что PLMX представляет собой некий средний стандарт.

В PL/M, нет встроенного определения FALSE и TRUE. Хотя булевы операторы (сравнения) выдают 0 и 255. В операторе IF, как и в Си можно подставлять не только булевы выражения, но и числа и переменные, и при этом FALSE считается 0, а TRUE в IF это уже не обязательно 255, а м.быть любое другое число отличное от 0.

Т.е в PL/M в качестве условия в IF можно использовать не только булево выражение, но и переменную типа BYTE, а также функцию (не процедуру), как и в Си. Хотя понятия функция в PL/M отсутствует, имеется ввиду процедура возвращающая байт. Т.о допустимо писать IF CHECK THEN... где CHECK это м.быть и переменная и даже процедура возвращающая байт. Благодаря этому не требуется применять промежуточную переменную с типом BYTE.

Нетрудно заметить, что программу на PL/M несложно конвертировать в программу на Паскале (а наоборот из Паскаля в PL/M - не всегда, лишь при использовании ограниченного набора операторов Паскаля). Можно даже автоматизировать такую конверсию с помощью специально написанной программы конвертора. Учитывая, что уже существуют программы конверторы из PL/M в Си, то и конвертор из PL/M в Паскаль возможен.

Наличие двух полностью идентичных исходников позволит оценить эффективность кодогенерации. Надеюсь в ближайшие годы написать сравнительно большую программу на PL/M и для оценки потом конвертировать её в исходник на Паскале и странслировать. Тогда будет сразу ясно какой из компиляторов и насколько эффективнее. Кстати, где-то читал, что до появления компиляторов Си именно язык Паскаль был внутренним языком фирмы Microsoft.

Ещё есть такой довольно известный антикварный язык программирования называемый PL/I, который очень хвалили в литературе и который, якобы, очень любили советские программисты для программирования ЕС ЭВМ. Удачно, что есть его компилятор и для CP/M-80 называемый PLI (он, как и сама CP/M, производства фирмы Digital Research).

Хотя некоторые "знатоки", не попробовав сами, лишь на основании штампов, т.е текстов из Википедии, утверждают, что этот ЯВУ, якобы, очень громоздкий и не идёт ни в какое сравнение по эффективности с PL/M. Маловероятно, что фирма стала бы делать неэффективный компилятор для 8-ми разрядки прекрасно зная скромные аппаратные возможности систем на базе CPU КР580. Скорее всего компилятор PL/I не хуже, чем компилятор PL/M, в нём не повторены все громоздкости PL/I для майн-фрейма IBM-360, т.к данный компилятор является лишь подмножеством этого ЯВУ. А главное, - сам этот язык очень похож на PL/M. Потому предположительно, программы на PL/M несложно конвертировать в программы для PL/I. Это также сразу позволит сделать вывод об сравнительной эффективности обоих компиляторов.

Кстати, исходнику игры CHESS, кто-то в Интернете сдуру присвоил расширение PL/M, а на самом деле это исходник не на языке PL/M, а на языке PL/I. В преамбуле даже написано, что эта игра была написана программистом с инициалами JWB из фирмы Digital Research и использовалась для тестирования компилятора PL/I при его разработке. Вероятно этот PL/I от Digital Research очень близок к PL/M и был назван PL/I лишь из-за авторских прав. Т.к права на PL/M уже были проданы и Digital Research не имела права продавать компилятор PL/M. Даже ключи трансляции в PL/I те же самые. И, кстати, похоже по сравнению с PLMX, компилятор PL/I транслирует во много раз быстрее, - он транслирует 700 строк за одну минуту 45 секунд, а PLMX транслирует 300 строк за 10 минут.

Даже, если компилятор PL/I окажется существенно хуже, чем компилятор PLMX (что очень маловероятно), то, т.к PL/I работает под TSR эмулятором CP/M для MSDOS, отчего компиляция происходит мгновенно, может быть будет быстрее писать и отлаживать программу на PL/I используя только те функции, что есть и в PL/M. А закончив разработку и отладку, если надо получить более эффективный код можно (внеся минимальные коррекции) странслировать этот исходник с помощью PLMX.

Освоив PL/M, думаю несложно будет переключиться на PL/I, ввиду похожести синтаксиса. Если в начале 90-тых имея компилятор PL/I я не смог им воспользоваться ввиду отсутствия учебников и документации, то сейчас не проблема скачать фирменное описание языка, хотя бесплатных учебников в электронном виде не нашёл, они продаются (и задорого) лишь в виде бумажного носителя. Сейчас читаю документацию по PL/I и позднее собираюсь попробовать писать программы для КР580 и на языке PL/I. Компилятор PLI, в отличие от компиляторов PL/M, позволяет использовать целые числа с бОльшим диапазоном, целые числа со знаком, числа с плавающией точкой, строки, многомерные массивы и структуры.

Есть ещё один вариант для облегчения написания чисто системных программ на PL/M. Cуществует компилятор PL/M для процессора 8086 работающий в MSDOS. Cкачать этот компилятор можно вот здесь. Тогда, имея Windows, такую, что прогоняет программы MSDOS (Win-98, Win-ME, Win-XP) можно писать и отлаживать программу на PC. А готовую программу уже можно странслировать компилятором PL/M-80. Кстати, при этом можно использовать и модули на ассемблере. Только переводить ассемблерный текст в мнемониках 8086 в мнемоники КР580 придётся вручную, т.к есть конвертор для конверсии из ассемблера КР580 в ассемблер 8086, а наоборот - нет.

Но эта идея годится только для чисто системных программ, т.е программ не лезущих в экран 8-ми разрядки и не использующих вызовов его ПЗУ. Так можно писать корректные CP/M-программы пригодные для любых CP/M-машин. В принципе так можно писать и экранные программы, только придётся на этапе отладки использовать упр.коды драйвера ANSI.SYS, т.к для MSDOS я до сих пор не нашёл драйвера VT52.SYS. Да и написать такой драйвер вывода для MSDOS самостоятельно несложно, даже работающий в графич.режиме (сам драйвер текстового вывода для граф.режимов у меня есть, надо добавить часть упр.кодов и сделать драйвер резидентным TSR). Перед окончательной трансляцией отлаженной в среде MSDOS PL/M-программы для работы уже под CP/M и в кодах КР580, останется только заменить упр.коды консоли, поставив в исходнике соответствующий ключ условной трансляции.

Ещё было бы интересно найти компилятор PL/M или PLMX для других процессоров, особенно тех на которых нет опыта программирования на ассемблере. В частности, меня интересуют компиляторы для 8048 и 6800. В рекламе на PLMX упомянуто, что и для процессора 6800 есть (а точнее была в 1980 году) версия компилятора PLMX. Оригинального компилятора PL/M для 6800 не странслировали (что естественно из-за отсутствия исходника на фортране, который был только у фирмы Intel).

Т.о для процессора 8080 сразу же при его появлении в начале 1974 был доступен ЯВУ PL/M, а для 6800 подобного компилятора хоть какого-то ЯВУ не было. До тех пор пока в 1976 году фирма Motorolla для поддержки разработок для своего процессора 6800 не разработала кросс-компилятор языка близкого по возможностям к PL/M (т.к он также производный от PL/I и в литературе характеризуется как "PL/I like language"). Первоначальное отсутствие ЯВУ для 6800, возможно, также сыграло свою роль в том, что процессор 8080 получил большую популярность в промышленности.

Этот язык называемый MPL-6800 - немного более мощный, чем PL/M-80 (т.к имеет работу со строками, структуры, многомерные массивы и целые числа имеют знак). Про этот ЯВУ тоже написано, что он очень эффективный в плане кодогенерации. Почитав описание языка MPL-6800 можно заметить, что лексика и синтаксис этого ЯВУ немного отличается от лексики PL/M (не используются завершающие точки с запятой и символы сравнения иные). Т.к в 1976 году для МП-систем на базе самого процессора 6800, ещё не было ни дисковода, ни ОС, то этот компилятор, как можно прочесть в документации, работал на майн-фреймах Xerox Sigma 9 и GE MARK III. Т.к сейчас ни у кого нет этих реальных машин и нет эмуляторов этих компьютеров, то этот кросс-компилятор для процессора 6800 можно считать утраченным.

Хотя есть небольшой шанс, что в середине 80-тых для программирования однокристаллов типа 6801/6803 исходник этого компилятора был странслировал в кросс-версию компилятора этого языка работающую на PC. В принципе существуют современные коммерческие компиляторы PL/M для выпускаемых и сейчас однокристаллов семейства 680x (т.е 6801/6805/6811/6812), но они (кроме 6801) несовместимы с 6800. Так что реально из ЯВУ для программирования под CPU 6800 сейчас доступен только кросс-компилятор Паскаля для MSDOS из программного обеспечения компьютера Пылдин-601.

- - - Добавлено - - -

При написании программ для ИРИШИ встаёт вопрос для какой среды делать программу. По сути есть две среды, это CP/M для карты 2 на 48К при экране напрямую доступном из программы CP/M и CP/M на 64К для карты 1 (или 3), когда экран напрямую программе недоступен. Программа работающая в карте 2 и не использующая CP/M-вызовов может считаться программой для среды монитора ИРИШИ и может загружаться с магнитофона. Хотя использовать программы загружаемые с магнитофона бессмысленно и неудобно.

CP/M на 64К более полноценна как DOS (позволяет использовать фирменные программы CP/M), а CP/M на 48К имеет плюсом то, что при наличии внешнего привода может работать с базовым объёмом ОЗУ (т.е без расширения ОЗУ, как минимум до 128 кб, что необходимо для CP/M на 64К). Оказалось, что диспетчер памяти ИРИШИ вполне удобен для работы с экраном из DOS на 64К.

Работа с графикой из программ для карты 1 делается так. В графической программе (которая для CP/M 64К может иметь размер до 57 кб), процедуры работающие с экраном располагают в областях 0...3FFF или 8000...BFFF, которые не переключаются при включении карты 2 (в которой экран включен с C000 и доступен для прямой записи). Тогда при включении карты 2 в адресном пространстве находится и 32 кб кода для работы с экраном и сам экран.

В компьютерах с цельно банковой коммутацией для работы с экраном приходится из банки программы в банку где доступен экран пересылать код драйвера работающего с экраном. В ИРИШЕ благодаря грамотному диспетчеру памяти это делать не требуется, - просто включаем экран, делаем на него вывод, а затем снова отключаем, возвращая расположенный в ОЗУ выше C000 код DOS. Примерно также сделано во Львове, где экран с 4000, чтобы не мешал, тоже выключается из пространства процессора. Такая архитектура ИРИШИ позволяет иметь свободными для программы все 64К и без ухищрений работать с экраном программой написанной на ЯВУ.

_________________
***
barsik
barsik
Мастер++

Сообщения : 573
Дата регистрации : 2016-11-10

Вернуться к началу Перейти вниз

ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Empty .

Сообщение  barsik в Чт Сен 19 2019, 20:46

7
Удалось заставить компилятор PLMX работать в MSDOS, что существенно упрощает его использование и ускоряет разработку программ. Ранее в первых экспериментах с PLMX у меня не получилось заставить PLMX транслировать в MSDOS под TSR-эмулятором CP/M. Из-за этого я стал транслировать не в эмуляторе CP/M для MSDOS, а в эмуляторе ретро-компьютера в котором эмулируется и CP/M. Из-за этого время затрачиваемое на один цикл модификации исходника получалось большим.

Проблема в том, что, хотя эмулятор ОРИОНА, которым я пользуюсь, позволяет вручную включить максимальную скорость эмуляции, задав константу торможения 0, но ввод команд CCP удаётся делать только при включении низкого (т.е родного) такта Z80. Это из-за того, что при эмулируемом такте Z80 в ~100 МГЦ даже при сАмом коротком нажатии на клавишу вводится не один символ, а десятки (т.к в используемом драйвере клавиатуры есть автоповтор, а время нажатия в 0.75 секунды до начала автоповтора отсчитывается программно). Потому приходится постоянно вручную переставлять константу торможения эмулятора. В итоге на трансляцию уходит хоть и не 15 минут, а около минуты, но это всё-равно утомительно.

Потому недавно, считая, что завис происходит из-за неполноценного эмулятора CP/M работающего под MSDOS, я попытался найти эмулятор CP/M в котором этот компилятор работает, но в ходе экспериментов случайно выяснил почему под 22NICE компилятор PLMX у меня зависал. Оказалось, причина в том, что компилятор PLMX сдуру сделан так, что по умолчанию (т.е без указания специальных ключей переназначения) выводит листинг на принтер.

В моей CP/M для ОРИОНА сделано так, что готовность принтера всегда есть и при попытке печати на несуществующем принтере зависа на ожидании готовности принтера не происходит. Благодаря этому проблем при компиляции PLMX и нет. А в эмуляторе CP/M 22NICE печать на принтер переадресуется на реальное устройство 'LPT:' имеющееся в MSDOS. В итоге (вероятно из-за Windows XP) компилятор PLMX просто зависает, ожидая готовность принтера. Это происходит скорее всего из-за того, что Windows не позволяет программам обращаться в порты (в том числе и в порт LPT). Соответственно, исправляется эта проблема легко. Достаточно запускать PLMX не командой

A> PLMX PROG<ВК>

а командой с ключом переназначения вывода листинга трансляции на экран (вместо принтера):

A> PLMX PROG ; L+C+<ВК>

Пробел после имени транслируемой программы перед точкой с запятой обязателен. В этом случае компилятор не делает вывод на принтер и зависа не происходит. Т.о сам компилятор PLMX, как и остальные CP/M-компиляторы, не использует никаких особенностей CP/M (использует только самые стандартные функции BDOS) и соответственно работает в любом эмуляторе CP/M под MSDOS (т.е даже в таком, в котором дискета не эмулируется, а вызовы функций CP/M просто переадресуются соответствующим процедурам MSDOS) и потому, естественно, будет работать и в MSX-DOS.

Т.к компилятор ассемблера M80 от Microsoft и линковщик LINK от Digital Research также без проблем работают под MSDOS-эмулятором 22NICE, то имея Windows XP (или другую ОС, что позволяет запускать MSDOS программы), можно транслировать PL/M программы тратя на трансляцию всего несколько секунд. Собственно трансляция выполняется ещё быстрее (даже с учётом ролика целого результирующего листинга в окне MSDOS), но после каждого этапа трансляции надо смотреть результат и, если ошибок нет, нажимать пробел для продолжения или ^C, чтобы прервать исполнение BAT-файла.

Недавно вот здесь https://zx-pk.ru/threads/30893-fork-sdcc-dlya-protsessora-8080.html?p=1027325&viewfull=1#post1027325 прочитал (не написано чью) фразу:

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

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

Обычно грамотная программа состоит из многих модулей самОй программы и также нескольких библиотечных модулей. Не знаю о каком размере исходника идёт речь, но я транслировал одномодульный фрагмент дающий на выходе аж 6 кб результирующего кода и проблем не было. Возможно автор фразы сдуру использовал CP/M с низким уровнем TPA (а TPA CP/M в грамотных эмуляторах имеет максимально возможный размер аж в 63.75 кб). В ближайшие дни, специально для проверки данного утверждения на практике, собираюсь составить одномодульную программу огромного размера и странслировать.

Так что вообще никакой проблемы тут нет. Обычно основной модуль как раз имеет маленький размер, а остальные модули можно мельчить как угодно (хоть по одной процедуре в модуле). Даже, если ограничение на размер за раз транслируемого исходника существует, то только врождённый идиотизм может помешать разбить огромную одномодульную программу на удобные модули мелкого размера.

Упомянутый по вышеприведённой ссылке PLM-1800 - это вовсе не компилятор PL/M-80 от отечественной СМ-1800, как можно сразу подумать, а это компилятор PL/M для антикварных (но выпускаемых до сих, хотя и не ставших очень популярными) микропроцессоров из серии 1800 (RCA 1801 и RCA 1802).

- - - Добавлено - - -

Сдохли все данные винчестера. Ничего особо важного не утрачено, т.к резервные данные я храню в заоблачных хранилищах и периодически делаю копию всего важного на 32 Гб microSD (с помощью карт-ридера для них). Но пропало всё написанное на PL/M и, к сожалению, всё, что было написано на Паскале МТ+ (и это теперь, увы, не восстановить, т.к уже забыто). Исходники на PL/M это был редактор фонтов (~300 строк), редактор текста (~1000 строк) и чуть-чуть кода для CP/M-нортона. На эксперименты на PL/M было затрачено более 150 часов, но теперь заново написать всё то же самое смогу менее, чем за 20 часов.

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


Последний раз редактировалось: barsik (Чт Сен 26 2019, 00:22), всего редактировалось 1 раз(а)

_________________
***
barsik
barsik
Мастер++

Сообщения : 573
Дата регистрации : 2016-11-10

Вернуться к началу Перейти вниз

ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Empty .

Сообщение  barsik в Чт Сен 26 2019, 07:16

8
Компилятор PL/I от Digital Research был для CP/M и потому был всем доступен, а компилятора PL/M для CP/M (если не учитывать мало распространённый PLMX ценой в $1000) не было. Компилятор PL/M был только в варианте для майн-фреймов, а многие даже в Америке не могли себе позволить купить дорогой майн-фрейм. Потому компилятор PL/I от DRI хвалили в литературе, а PL/M даже не упоминали.

В пользу лучшего качества PL/I говорит то, что компилятор PL/M для микроцессоров разработан раньше и всего одним человеком (и даже не программистом, а профессором коледжа), а компилятор PL/I для CP/M написан на 7 лет позже и уже коллективом профессиональных программистов фирмы Digital Research.

И как язык PL/I даже в версии для CP/M, как минимум, вдвое сложнее, потому даёт программисту больше возможностей. Некоторые даже считали, что PL/I лучше, чем Си. Возможно, как раз из-за наличия для процессора 8080 хорошего компилятора PL/I, компилятор PL/M не имел смысла и потому не получил распространения. Об эффективности этой версии компилятора PL/I писал Г.Килдэл в своих мемуарах:
Гарри Килдэл пишет:PL/I, выпущенный фирмой Digital Research в 1980 году, был с большим преимуществом лучшим компилятором разработанным для процессора 8080. Это был превосходный язык и даже программисты на ассемблере не могли превзойти машинный код, который он создавал.
Из этой цитаты следует, что компилятор PL/I от Digital Research для CP/M лучше в том числе и чем компилятор PL/M от Intel для ОС ISIS (о свойствах которого Г.Килдэл был, естественно, в курсе).

Кстати, ознакомился с этим компилятором от Intel в кросс-версии, - посмотрел кросс-компилятор PL/M перетранслированный под Windows из версии компилятора PL/M 4.0 для ОС ISIS выложенный здесь. Для его получения исходник компилятора PL/M для ISIS написанный на PL/M и сопутствующие утилиты конвертировали в исходник на Си и странслировали чем-то, что использует DLL из Visual Studio (потому при запуске утилиты LINK.EXE в Win XP не хватало одного DLL; пришлось отдельно добавлять его).

Процесс компиляции этим компилятором громоздкий, куча этапов трансляции с последующей обработкой полдесятком, не пойми-что делающими утилитами (добавляется обработка утилитой LOCATE настраивающая на адреса, компоновщик LINK не даёт кода, а только объединяет модули и только утилита OBJCPM даёт код, затем делается ещё куча каких-то преобразований другими утилитами о которых нет вообще никакой информации). Приложенный к дистрибутиву BAT-файл создаёт программу для ZX-Spectrum, а как создать программу для нормального компьютера не ясно.

Кстати похоже, одной из причин почему ОС ISIS хуже, является то, что ISIS имеет в 1.5 раза больший объём кода, чем CP/M (ISIS занимает целых 12 кб ниже адреса $3000, видимо это из-за того, что странслировано на PL/M, в то время как CP/M c версии 2.0 была переписана на ассемблер).

Сейчас, когда я научился запускать CP/M-компилятор PLMX прямо из MSDOS (т.е без больших потерь времени), меня вполне устраивает и PLMX; никаких недостатков в нём не обнаружил. Наличие структур было бы полезно, но их отсутствие даже не огорчает. К тому же у PLMX уже есть библиотека ввода/вывода и поддержка CP/M, а для обсуждаемого кросс-компилятора ничего похожего нет, голый генератор кода без поддержки CP/M или привязки к ROM-BIOS конкретной машины. Если хоть какой-то ввод/вывод и поддержка ОС в этом компиляторе и есть, то для ОС ISIS. Т.о пока никакой пользы от этой выкладки на гитхабе нет, хотя сам этот кросс-компилятор по качеству производимого кода и реализованным более развитым возможностям языка, видимо, более качественный, чем PLMX.

Если верить книгам и словам разработчика, наиболее перспективным ЯВУ для КР580 является всё-же компилятор PL/I от Digital Research. Скачать PL/I для КР580 и документацию можно здесь.

Почитав руководство программиста, я обнаружил, что PL/I намного сложнее, чем (простой как апельсин и всем понятный) PL/M, не уступая по возможностям классическому Си. Кажется, там есть даже потоки, числа со знаками, плавающая точка и много других прибамбасов. Ясно, что чтобы всё это изучить требуется много ума и огромное количество энтузиазма. И если освоение и привыкание к PL/M у меня ушло более месяца, то на освоение PL/I может уйти несколько месяцев.

Сложность PL/I по сравнению с PL/M не способствует желанию им заняться, - на изучение документации и освоение этого ЯВУ потребуется время. Возможно через несколько месяцев разберусь и с PL/I, но пока буду пользоваться PLMX, - иначе будет обидно, что потратил время и энергию на его освоение. Тем более, что пока возможности и качество кода PLMX меня устраивают. На досуге буду почитывать PLI Programmers Guide и, надеюсь, через пару месяцев смогу написать и странслировать первые простейшие программы. И тогда узнаю, выдаёт ли компилятор PL/I более эффективный выходной код, чем код созданный компилятором BDS Си или компилятором Паскаля MT+.

_________________
***
barsik
barsik
Мастер++

Сообщения : 573
Дата регистрации : 2016-11-10

Вернуться к началу Перейти вниз

ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M. Empty Re: ПО. ПЭВМ "Ириша". Программирование для ИРИШИ на PL/M.

Сообщение  Спонсируемый контент

9

Спонсируемый контент


Вернуться к началу Перейти вниз

Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения