1 Отредактировано pvaWatson (21-10-2019 09:52)

Тема: Пакет MADPascal + MADAssembler

Привет всем!

В дополнению к соседней теме о CC65, но для тех кто предпочитает Pascal, а не С (каковым я и являюсь) возможно заинтерисует кросс-компилятор с паскаля под 6502 - MADPascal.

Разработан польской командой программистов под Atari (http://mads.atari8.info/doc/madpascal.html) на основе  реализации языка паскаль от Терешкова В. под x86 (https://habr.com/ru/users/tereshkov/posts/). Представляет из себя транслятор с языка Pascal в ассемблерный код, который затем транслируется в объектный код транслятором с ассемблера 6502 от тойже команды (MADAssembler http://mads.atari8.info/ ).

Реализует подмножество языка Pascal в объёме близкому к TurboPascal 6.0 с некоторыми ограничениями.
Изначально они его разрабатывали для Atari так что напрямую аппаратно зависимые процедуры модулей входящих в комплект использовать не получится, но, если использовать тексты библиотек как основу, можно их модифицировать с учётом аппаратных особенностей АГАТа.

Из достоинств - как и Турбо-Паскаль позволяет создавать проекты как на чистом паскале, так и с ассемблерными вставками в коде и/или с внешними асм-процедурами. Набор текста можно делать в каком-нибудь текстовом редакторе (например Notepad++) или в современной IDE Паскаля (например Lazarus, Delphi или тотже BorlandPascal 7.0). Если использовать IDE, то можно также частично сделать отладку - только надо закомментировать системно-зависимые поцедуры/асм-вставки.



Для примера во вложении программа рисования линий в двух графических режимах АГАТ-9 - МГВР и ЦГВР.
Чтобы откомпилировать пример надо скачать исходники MADPascal с https://github.com/tebe6502/Mad-Pascal,

в корень каталога положить трансляторы MADPascal "mp.exe" и MADAssembler "mads.exe" (также есть во вложении).

компилируем

mp J:\MAD\MADPascal\projects\Primer\LineTest.pas -code:8001 -zpage:58

mads J:\MAD\MADPascal\projects\Primer\LineTest.a65 -b:8001 -l -x -t -i:J:\MAD\MADPascal\base\ -o:J:\MAD\MADPascal\projects\Primer\LT.BIN

где

"J:\MAD\MADPascal\projects\Primer\" - путь с исходниками примера (LineTest.pas и GR.pas);
"J:\MAD\MADPascal\base\" - путь к библиотекам для mads (каталог "base" в корне исходников MADPascal);
"8001" - шестнадцатиричный адрес начала генерации кода;
"-zpage:58" - адрес с которого в нулевой странице будут располагаться необходимые для программы ячейки (адрес $58 - выбрал с учётом того чтобы сильно не мешать ИКП бейсику и дос3.3) - будет занято 24байта под "систему" и 64байта под эмуляцию стека - т.е. в сумме 88байт;

В итоге получаем файл LT.BIN который складываем с помощью утилиты dos33c2w (с этого сайта) в какой-нибудь файл образа диска АГАТ с бейсиком или ИКП по "F9\Импорт\Двоичный B-файл без перекодировки".

Для запуска в бейсике набираем

BRUN LT.BIN,A$8001

(Некоторое замечание по mads - в оригинальной версии от разработчиков в итоговый бинарный файл вначале добавляются два байта "$FFFF". Возможно это имеет значение для Atari, но в случае АГАТа они не нужны, так что во вложении модифицированный файл mads.exe - ничего не добавляющий в префикс результата.)

Post's attachments

Attachment icon Primer.zip 511.04 kb, 243 downloads since 2019-10-21 

2

Re: Пакет MADPascal + MADAssembler

1) На агате есть "Дельта-паскаль" , интересно было бы сравнить качество кода, который они генерируют.

2) Если у них есть ассемблер, то может быть есть и редактор связей и, соответственно, возможность сразу описать FIL-контейнер, чтобы обойтись без импорта через dos33c2 ?

3) Если есть редактор связей, то может быть можно делать сборку загружаемого файла из группы библиотек, в т.ч. написанных на асме ? Т.е. часть проги на паскале, а часть - на внешнем ассемблере ? С автоматической сборкой ссылок, конечно.


ЗЫ Тоже люблю паскаль за его строгую красивую типизации и runtime- контроль диапазонов всего и вся.
Позволяет на этапе компиляции ловить много багов, и долавливать остальные во время работы.
У C этим проблемы (хотя у нынешних компиляторов уже столько warning'ов есть, что кой что удаётся отловить на этапе сборки), у остальных модных нынешних языков с этим просто капец :(, хоть вешайся (PERL, PHP, Javascript...).

3 Отредактировано pvaWatson (21-10-2019 16:20)

Re: Пакет MADPascal + MADAssembler

1) Хороший вопрос - самому интересно сравнить. И если с мад-паскалем всё просто - на выходе получается уже готовый asm текст, который можно посмотреть в любом редакторе, то с дельта-паскалем, как понимаю, надо выдернуть объектный файл и дизассемблировать (например с помощью IDA Pro).

2) Как понял из предварительного поверхностного изучения mads - это многопроходной ассемблер + линковщик в одном флаконе. Но вот по поводу того чтобы сразу на выходе получить FIL-файл, идея хорошая, но пока не разбирался (в том числе и потому, что формат FILфайла ещё не изучал :-) ).

3) В самом паскале импорт внешних библиотек возможно только либо на уровне модулей паскаля (uses), либо на уровне ресурсного  .asm файла в формате мад-ассемблера, который будет скомпилирован и объединён с паскаль-программой.

Вообще - с одной стороны мад-паскаль создаёт несколько громоздкий код (особенно это касается условий if-then-else). С другой стороны в итоговом файле остаются только те функции, что используются в паскаль программе. Причём всё "лишнее" удаляется настолько радикально, что иногда это приводит к сложностям с вызовом процедур в ассемблерных вставках - т.к. мад-паскаль не проверяет код в ассемблерной вставке, то, если процедура вызывается только из ассемблера - она будет удалена.
Зато есть возможность привязать переменную к фиксированной ячейке памяти (ключевое слово absolute) - удобно для размещения переменной в ZeroPage или мапить на адреса ввода-вывода.
Из встроенного ассемблера можно вызывать любую паскаль процедуру и использовать переменные из раздела var.
Есть перегрузка процедур. Реализованы объекты и указатели, а также процедуры-обработчики прерывания - на выходе формируется код возврата не rts, а rti. Ну и т.д. (http://mads.atari8.info/doc/madpascal.html)

Мад-ассемблер - макро-ассемблер под 6502(65816) с широкими возможностями (не буду подробно расписывать - посмотреть можно здесь http://mads.atari8.info/mads_eng.html ). Есть возможность объединять библиотеки с CC65. :-)
Единственное, синтаксис несколько отличается от ассемблера школьницы, в частности в командах с неявным использования регистра A типа "LSR A" - в mads будет "LSR @", двоичные данные не ":", а "%" и ещё несколько различий, но, думаю, можно быстро адаптировать существующий код.

4 Отредактировано Voldemar0 (22-10-2019 06:58)

Re: Пакет MADPascal + MADAssembler

Как он организует стек параметров процедур ? На аппаратном стеке или создаёт свой ?

Насколько эффективно компилируются какие нибудь конструкции типа " integer a, b; a := a + b; " ?
У cc65 в таком случае начинались тяжелые игры со стеком вместо простого "clc ; lda a+0 ; adc b+0 ; sta a+0; lda a+1 ; adc b+1 ; sta b+1".

Что насчёт стандартных процедур (writeln, readln) ? Они реализованы или всё сам ?

> Есть возможность объединять библиотеки с CC65
Ну если есть, то вроде как можно значит и делать сборку на разных языках...

> Единственное, синтаксис несколько отличается от ассемблера школьницы
Так он везде отличается. У школьницы LSR A , у бейсика LSR, что там у ca65 - я даже не помню :).
И ещё надо смотреть опции, например, у ca65 некоторые аспекты поведения по синтаксису прямо директивами внутри
исходника своей проги можно задать.

> (в том числе и потому, что формат FILфайла ещё не изучал :-) ).
Он не сложный, можно из темы про ca65 взять, там где-то в примерах есть.
Или в теме про w5100 - там последние версии исходника для ca65, который формирует FIL.


:) прикольно, он FPCшкой собирается ?
Тогда можно подправить сразу, если чего не будет хватать :)

5

Re: Пакет MADPascal + MADAssembler

> Как он организует стек параметров процедур ? На аппаратном стеке или создаёт свой ?
Стек программный на базе ячеек в ZP + регистр X. Используется только для передачи параметров, которые копируются в локальные переменные. Память под внутренние переменные выделяется статически, так что, по идее, рекурсия должна работать только если не используются локальные переменные (факториал точно работает :-) ).
Выглядит передача параметров так:

   187 802D B5 70 8D 7D 82        mva :STACKORIGIN,x Z
   188 8032 B5 80 8D 7E 82        mva :STACKORIGIN+STACKWIDTH,x Z+1
   189 8037 CA                dex                        ; sub bx, 1

где макрос MWA A B = LDA A + STA B
STACKORIGIN - адрес начала стека
STACKWIDTH - размер стека в 32х битных ячейках (т.е. полный размер стека в байтах = STACKWIDTH*4)
регистр X - указатель на вершину стека

на мой взгляд более или менее адекватно сделано. Как результат <" integer a, b; a := a + b; "> компилируется в нормальную конструкцию:

   219 8066 AD 7F 82            lda A
   220 8069 18 6D 81 82            add B
   221 806D 8D 83 82            sta C
   222 8070 AD 80 82            lda A+1
   223 8073 6D 82 82            adc B+1
   224 8076 8D 84 82            sta C+1

(add=clc+adc)

Кстати, из-за того что локальные переменные статические, есть формальная возможность к ним обратится из ассемблерной вставки из любого места программы.

Вообще оптимизации кода иногда неплохо реализованы - например конструкцию вида "a: word; b,c:byte; a:=b*256+c" преобразует в "lda b; sta a+1; lda c; sta a".

> Что насчёт стандартных процедур (writeln, readln)? Они реализованы или всё сам ?
Реализованы, но не для АГАТа. :-) - поэтому ещё не использовал их и, уверен, что придётся реализовывать их самому.

> :) прикольно, он FPCшкой собирается ?
Точно (а также дельфями 7 и выше) и mads тоже на паскале написан.

Кстати, сами разрабы адекватно реагируют на выявленные ошибки: когда им написал по поводу ошибки с возвратом значения указателя из процедуры, уже на след. день выложили исправленную версию компилятора https://atariage.com/forums/topic/24091 … l/page/13/

6 Отредактировано pvaWatson (25-10-2019 09:13)

Re: Пакет MADPascal + MADAssembler

Сделал на PowerShell (Windows) скрипт создающий FIL-файл из результирующего бинарного файла после компиляции и выходных данных от mads перенаправленных в файл. Собрал команды вызова компилятора mp, mads и вызов скрипта преобразования в FIL-файл  в одном  командном файле (архив во вложении).
Единственное надо однократно в командной строке powershell разрешить выполнение неподписанных скриптов (с правами администратора):

Set-ExecutionPolicy Bypass -Force

и изменить пути/имена к файлам в скриптах .bat и .ps1

Update - встроена перекодировка имени программы из ANSI Windows в кодировку АГАТа.
(информация о созданию FIL-файла и таблица перекодировки взята с соседней ветки по CC65 из поста Voldemar0 - за что огромное спасибо :-) )

Post's attachments

Attachment icon Scripts.zip 1.69 kb, 232 downloads since 2019-10-24