А теперь немного о том, как устроен
nedoPC SDK (точнее его дедушка RW1P2):
- на верхнем уровне есть 2 каталога - INC и LIB:
-- в INC находятся инклудники с константами для языка роботов (инклудятся до функции main)
-- в LIB находятся инклудники с описанием функций для языка роботов (инклудятся после функции main), а также подкаталоги с названием процессоров (сейчас только I8080 и Z80), в каждом из которых есть:
--- файл __RULES с описанием правил трансляции байткода роботов в ассемблер выбранного процессора
--- файлы подсистем на ассемблере для выбранного процессора как _SAY.A, _CLIB.A и т.д.
--- файлы основных системо-зависимых ассемблерных подпрограмм для всех поддерживаемых систем с выбранным процессором (например RADIO.A, ORION.A и т.д.)
--- опциональные подкаталоги с именами поддерживаемых систем, где могут лежать дополнительные файлы (заголовки бинарных файлов типа EXE, заглушки для TAP и т.д.)
Наибольший интерес вызывает файл __RULES:
https://gitlab.com/nedopc/sdk/-/blob/master/sdk/LIB/I8080/__RULES (живёт на гитлабе с июня 2018)
Комментарии в нём идут как в C++ после // и далее файл поделён на секции, разделяемые звёздочками - слова после звёздочки дают секции название (а звёздочка без названия просто закрывает предыдущую секцию). Наиболее часто встречаемые секции - это правила трансляции байткода - когда после звёздочки следует шестнадцатиричное число, например:
Code: Select all
// 0x68 M // COLOR varn // set current color
*0x68 0x00 %w1
MVI_A, %w1
STA _COLOR
*0x68 %m1
#mem1
MOV_A,L
STA _COLOR
*
Здесь можно видеть 2 секции - обе относятся к трансляции байткода 0x68 (COLOR), но первая секция более детальная, а вторая - более общая (общая секция сработает, если ни одна детальная не прошла проверку - точнее секции вычитываются одна за другой и срабатывает первая, которая подошла, поэтому более общие секции надо ставить после детальных). Спец-идентификаторы %wN (где N - порядковый номер) означают 2-байтовое слово, %mN означают переменную языка Robby (может занимать от 2 до 5 байт), ещё бывают %aN для адресов и %bN для байтов. Они далее используются прямо как есть (MVI_A, %w1) либо путём вставки спец-кода для расшифровки переменных языка Robby - #memN где N это порядковый номер переменной, соответствующий %mN. С решётки начинаются и другие спец-коды (не только #memN) - ещё бывают #addsub (для указания кросс-компилятору какие файлы с подпрограммами нужно инклудить в результирующий исходик), #error (для прекращения работы кросс-компилятора с рапортованием ошибки), #genlab (для генерации временных меток в месте вставки кода) и т.д.
Кроме того секции выделяемые звёздочками могут быть специальными - например секция *ASM TABLE предназначена для скармливания ассемблеру RASM в качестве таблицы трансляции, *COMMENT указывает, что используется в качестве отделителя комментария в выбранном ассемблере, *EXPR 0x?? используется для трансляции байткодов стековой машины (скомпилированные длинные выражения) и т.д.
Вобщем вот как-то так...
P.S. Оказывается у меня есть нереализованные спец-коды, например передача управления по адресу из массива #atable:
Code: Select all
//-0x43 M // GOTO var
*0x43 0x00 %w1
JMP %j1
*0x43 %m1
#mem1
#atable
PCHL
*
//-0x44 M // CALL var
*0x44 0x00 %w1
CALL %j1
*0x44 %m1
#genlab %l2
LXI_H, %l2
PUSH_H
#mem1
#atable
PCHL
%l2
*
P.P.S. По большому счёту с помощью такой системы правил можно транслировать не только ROBBY-байткод во что-то, но и вообще что угодно во что угодно (при необходимости добавляя новые спец-идентификаторы и спец-коды в транслятор), например из кода 8080 в PDP-11 и т.д.