Важная информация
RSS лента

3aRulem Печатное слово

Делаем связку Notepad + SjASMPlus + UnrealSpeccy (Black Cat / ERA Creative Group)

Рейтинг: 4.17. Голосов: 6.
_
Итак, нам надо подружить Notepad++ с ассемблером и эмулятором, дабы удобно редактировать исходные коды и прямо из него, никуда не выходя, компилировать их и запускать результат через эмулятор.

Сначала пару слов о том, почему именно Notepad++:
  1. Бесплатность.
  2. Поддержка одновременной работы с несколькими файлами.
  3. Настраиваемая подсветка синтаксиса.
  4. Возможность настройки сворачивания кода / комментариев.
  5. Поддержка проектов.
  6. Множество всевозможных плагинов (с некоторыми из которых на предстоит познакомиться).
  7. Просто нравится (привык я к нему).


Начнем. Установка Notepad++.

Тут все просто.
  1. Отправляемся на https://notepad-plus-plus.org/ .
  2. Жмем там Download, выбираем нужный нам вариант (есть инсталлятор, zip-архив, 7z-архив, а также особый сверхмалый 7z-архив, откуда вырезано все лишнее), скачиваем. Я обычно выбираю просто инсталлятор.
  3. Ставим Notepad++ через инсталлятор или распаковываем в нужное место из архива, смотря что выбрали пунктом выше. Тут, я думаю, вопросов возникнуть не должно никак.
  4. Есть только одна мелочь, если выбрали инсталлятор, во время установки, на странице выбора компонентов устанавливаемой программы не забудьте выбрать русскую локализацию в категории "Localization".
  5. И обратите внимание на следующую страницу в инсталляторе. Если вы хотите иметь возможность таскать с собой Notepad++ на флэшке, запретите ему хранить настройки в %APPDATA%, установив первую галочку на этой странице. Вторую галочку я обычно не устанавливаю. Третью (ярлык на рабочем столе) и четвертуя (использование старой иконки программы) - на ваш выбор.
  6. Все.


Настройка подсветки кода ассемблера Z80 и сворачивания блоков.

Итак, Notepad++ установлен, однако если открыть исходный файл ассемблера Z80, то никакой подсветки мы там не увидим, ибо встроенной подсветки для нашего асма там попросту нет. Не нашел я ее и в тех, что можно скачать с официального сайта (может быть просто плохо искал). Но выход есть. Во-первых, в Notepad++ есть возможность создания своего синтаксиса. Однако, это несколько утомительно. Но вам повезло! Ибо (мне-то деваться было некуда) я слепил за ночь такую подсветку (точнее просто взял готовую от другого редактора и вбил то, что там было в меню Notepad++). Сразу оговорюсь, то, что получилось в итоге, от идеала очень далеко, но уже лучше, чем совсем ничего. Дальше расскажу, как ее подключить.
  1. Копируем файлик z80.xml в ту папку, в которую мы установили (распаковали) Notepad++.
  2. Запускаем Notepad++.
  3. Идем в меню "Синтаксисы -> Задать свой синтаксис".
  4. В открывшемся диалоге жмем кнопку "Импортировать", выбираем наш файл (z80.xml)
  5. Получаем сообщение об успешном импорте. Теперь можно здесь же в списке "Пользовательский язык" выбрать "Z80 Assembler".
    Обратите внимание на то, что установилась галочка "Любой регистр" (ключевые слова будут подсвечиваться независимо от того, в каком регистре набраны) и в поле "Расширение" появилось расширение "a80" (именно его принято использовать для исходных текстов ассемблера Z80, по крайней мере не один я его использую). В принципе, с подсветкой все. В этом диалоге при желании потом можно покопаться и изменить подсветку по вашему вкусу.
  6. Еще одно замечание. Для файлов с расширением "a80" подсветка должна теперь включаться автоматически. Для файлов же с другим расширением эту подсветку можно подключить, выбрав ее в самом низу меню "Синтаксисы" (появится только после перезапуска Notepad++).


Теперь немного небольшого оффтопа. Когда я пилил эту подсветку, мне очень хотелось иметь возможность сворачивать произвольные блоки кода (не только многострочные комментарии). Возможность такая в Notepad++ имеется. Однако надо было придумать какие-то маркеры начала и конца блока, а так как была уже глубокая ночь, то ничего хорошего мне в голову не пришло. Поэтому, я считаю, что я просто обязан вам рассказать, как эти маркеры (теги) поменять на более удобные или осмысленные.

Для начала расскажу как работает эта фича Notepad++. В SjASMPlus, которым мы будем пользоваться в качестве ассемблера, есть два типа комментариев: многострочные (задаются парами символов /* и */ в начале и в конце комментария) и однострочные (задаются символами ; или //, кому как удобно). С многострочными все понятно, они имеют возможность сворачиваться по умолчанию, сразу же как только были заданны в подсветке. Однако то, что расположено внутри многострочного комментария - это всего лишь комментарий, а нам надо научиться сворачивать код. И вот с помощью однострочных комментариев можно именно этого и добиться. Для этого нам надо задать особые маркеры начала и конца блока. И вот как это будет выглядеть:

Код:
какой-то код
; какой-то комментарий МАРКЕР_НАЧАЛА_БЛОКА какой-нибудь еще комментарий
какой-то код
и еще какой-то код
; какой-то комментарий (или нет его не важно) МАРКЕР_КОНЦА_БЛОКА
какой-то еще код
Так вот те строки, где располагаются маркеры начала и конца комментария, для ассемблера и по сути обычные однострочные комментарии, код расположенный между ними ассемблируется, как обычный код. Но наличие этих пар (можно настроить тройки) маркеров, позволяют сворачивать блок.

Теперь о том, где это настроить. Ибо я для начала и конца блока выбрал ---> и <---, что вряд ли удобно.
  1. Идем в меню "Синтаксисы -> Задать свой синтаксис".
  2. Выбираем наш "Z80 Assembler".
  3. И тут же на первой вкладке "Стандартный", в группе "Свертывание в комментариях" задаем удобные нам маркеры. Их может быть несколько разных (указываются через пробел), но обязательно с соблюдением порядка. Маркер "Середина" - это что-то наподобие ELSE в IF...ELSE...ENDIF.


Во всем остальном подсветка вполне рабочая.

Далее. Дружим Notepad++ с SjASMPlus и UnrealSpeccy.

Что ж, подсветка - это конечно хорошо, однако мы сюда не на раскрашенные исходники смотреть пришли. Пора уже прикручивать наш редактор к ассемблеру и эмулятору.

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

  1. Для начала идем по адресу: https://sourceforge.net/projects/npp...files/NppExec/ и скачиваем оттуда плагин NppExec. Можно его установить и из меню Notepad++, но мы скачаем так (а то что-то у меня скачка плагинов изнутри Notepad++ барахлит). Скачиваем оттуда последнюю версию NppExec Plugin. Там есть ANSI и Unicode версии. Насколько я понял, ANSI предназначается для старых версий Notepad++, которые работают на ОС без поддержки Юникода (типа Windows 98). Поэтому качаем Unicode-версию плагина.
  2. Скачали, распаковываем архив с плагином в папку с установленным Notepad++ в подпапку "plugins".
  3. Запускаем (перезапускаем) Notepad++. В Меню "Плагины" должен появиться пункт "NppExec", а на панели инструментов кнопка "Show Console Dialog".
  4. Жмем эту кнопку, появится окно консоли. В нем мы будем видеть все сообщения от наших ассемблера и эмулятора. Однако их запуск нам предстоит еще настроить.
  5. Для этого мы напишем три простых скрипта. Первый будет компилировать проект с помощью SjASMPlus, второй запускать полученный образ диска в UnrealSpeccy, третий делать первое и второе подряд.
  6. Начнем с первого. Идем в меню "Плагины -> NppExec -> Execute...". Откроется диалог, в котором можно набрать небольшой скрип и тут же его запустить. Мы его пока запускать не будем, но наберем следующий скрипт:

    Код:
    // Скрипт компиляции проекта
    // Сохраняем все файлы
    npp_saveall
    // Сохраняем путь текущего редактируемого файла
    set current = $(FULL_CURRENT_PATH)
    // Переключаемся на основной файл проекта (должен быть открыт в 1-ой вкладке!)
    npp_switch $(#1)
    // Получаем полные имена файла меток и основного файла проекта
    set symbol_name = "$(CURRENT_DIRECTORY)\$ (NAME_PART).sym"
    set project_full_name = "$(FULL_CURRENT_PATH)"
    // возвращаемся на ранее открытую вкладку
    npp_switch $(current)
    // компилируем проект
    cd $(project_full_name)
    "<Полный путь к SjASMPlus>\sjasmplus.exe" --fullpath --sym=$(symbol_name) $(project_full_name)
    Последняя строка скрипта как раз и отправляет наш проект на компиляцию. ВАЖНО! На компиляцию отправляется тот исходник, который открыт в первой вкладке (это можно изменить, чтобы на компиляцию отправлялся текущий редактируемый файл, но так как у меня проекты обычно состоят из многих файлов и одного основного, мне так удобнее). Перед этим происходит попытка сохранения всех не сохраненных файлов и переключение на первую вкладку.
  7. Скрипт готов. Теперь логично его сохранить. Жмем "Save". Вводим имя нашего первого скрипта, например, z80complie. Снова жмем "Save". Можно идти настраивать дальше, но бы лучше сразу сохраним и два других скрипта.
  8. Выберем в списке <temporary script>, окошко очистится, и мы наберем в нем следующее:

    Код:
    // Скрипт запуска проекта
    // Сохраняем путь текущего редактируемого файла
    set current = $(FULL_CURRENT_PATH)
    // переключаемся на основной файл проекта (должен быть открыт в 1-ой вкладке!)
    npp_switch $(#1)
    // Получаем полное имя образа диска с откомпилированным проектом для запуска
    // (если вы компилируете в sna, поменяйте расширение на нужное)
    set image_name = "$(CURRENT_DIRECTORY)\$ (NAME_PART).trd"
    // Возвращаемся на ранее открытую вкладку
    npp_switch $(current)
    // Запускаем откомпилированный проект
    "<Полный путь к UnrealSpeccy>\unreal.exe" $(image_name)
    Здесь все аналогично первому скрипту.
  9. Аналогично п.7 сохраним сей скрипт под именем z80run
  10. Действуя, как в п.8, наберем скрипт "Сохранение+Запуск"

    Код:
    // Скрипт компиляции и запуска проекта
    // Сохраняем все файлы
    npp_saveall
    // Сохраняем путь текущего редактируемого файла
    set current = $(FULL_CURRENT_PATH)
    // Переключаемся на основной файл проекта (должен быть открыт в 1-ой вкладке!)
    npp_switch $(#1)
    // Получаем необходимые имена файлов
    set image_name = "$(CURRENT_DIRECTORY)\$ (NAME_PART).trd"
    set symbol_name = "$(CURRENT_DIRECTORY)\$ (NAME_PART).sym"
    set project_full_name = "$(FULL_CURRENT_PATH)"
    // Возвращаемся на ранее открытую вкладку
    npp_switch $(current)
    // Компилируем проект
    cd $(project_full_name)
    "<Полный путь к SjASMPlus>\sjasmplus.exe" --fullpath --sym=$(symbol_name) $(project_full_name)
    // Запускаем откомпилированный проект
    "<Полный путь к UnrealSpeccy>\unreal.exe" $(image_name)
    Тут все еще понятнее, это по сути просто два предыдущих скрипта вместе.
  11. Сохраним скрипт под именем z80complie_run.
  12. Скрипты готовы, теперь хотелось бы, чтобы они были под рукой. Для чего идем в меню "Плагины -> NppExec -> Advanced Options...".
  13. В группе "Menu items" устанавливаем галочку на "Place to the Macros submenu"
  14. Ниже в группе "Menu item", вводим имена пунктам меню и выбираем скрипты, которые они буду запускать. Например, в "Item name" введем "Компиляция Z80", в списке "Associated script" выберем "z80compile". Не забудем нажать кнопку "Add/Modify". Добавленный пункт появится в списке сверху. После создания пунктов меню для всех наших трех скриптов, их порядок расположения можно поменять кнопками "Move Up" и "Move down". Закрываем этот диалог. Notepad++ сообщит о необходимости перезапуска. Что ж, перезапустите его. Теперь в меню "Макросы" появились наши макросы. Но, кажется, я что-то говорил о горячих клавишах. Действуем дальше.
  15. Идем в меню "Опции -> Горячие клавиши...". На вкладке "Plugin commands" ищем наши Макросы, жмем "Modify" или кликаем 2 раза по строке с макросом, задаем горячую клавишу. Я задал клавиши F9, F10 и Shift+F10 для всех трех макросов.


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

Настройка переходов на ошибки из консоли.

Все просто. Меню "Плагины -> NppExec -> Console Output Filters...". На вкладке "Highlight" задаем следующую маску "%F%(%L%): error:*". Устанавливаем галочку для нее. А также цвет (например красный) и стиль шрифта. Жмем "OK". Снова пытаемся откомпилировать наш исходник с ошибкой. Замечаем, что строки с ошибками теперь выделены выбранным цветом. Попробуйте два раза щелкнуть по ней мышью. Удобно.

Теперь еще для полноты картины неплохо было заставить Notepad++ искать метки в открытых документах и выводить их в отдельной колоночке. Есть у Notepad++ такая фича, как отображение списка функций. Ее-то мы для этого и настроим.
  1. Для этого нам надо открыть на редактирование файл "functionList.xml" из папки с установленным Notepad++.
  2. Найти секцию <parsers> и запихать туда свой парсер следующего вида:

    PHP код:
    <parser id="z80_label" displayName="Z80 Assembler labels" commentExpr="((/\*.*?\*)/|(//.*?$)|(;.*?$))">
            <function
                    
    mainExpr="(^[\S]+)"
                    
    displayMode="$functionName">
                    <
    functionName>
                            <
    nameExpr expr="(^\S+)"/>
                    </
    functionName>
            </function>
    </
    parser
    Немного объясню, что тут к чему. В первой строке мы задаем идентификатор нашему парсеру (должен быть уникальным), имя ему (которое где-то должно отображаться, судя по названию) и (самое главное) регулярное выражение описывающие синтаксис комментариев нашего языка, для того, чтобы комментарии пропускались при поиске меток. Сразу оговорюсь, я совершенно не умею составлять регулярные выражения, поэтому я кое-как добился, чтобы работало, и этим доволен. В строке (или как это зовется в xml) "function" задается регулярное выражение для поиска строк (или как у меня, кусков строк) с метками - mainExpr и формат отображения найденных меток в списке. В секции "functionName" указывается еще одно регулярное выражение, извлекающее из найденных строк имена меток (в строке "nameExpr").
  3. Парсер готов, но это еще не все. Теперь идем вверх по файлу, находим секцию "associationMap" и прописываем туда наш парсер следующим образом:

    PHP код:
    <association userDefinedLangName="Z80 Assembler" id="z80_label"/> 
    где, "userDefinedLangName" имя нашего синтаксиса (должно быть таким же, как и при редактировании подсветки), а "id" - идентификатор нашего парсера.

    Либо можно сделать привязку по расширению так:

    PHP код:
    <association ext=".a80" id="z80_label"/> 
  4. Файл сохраняем.
  5. Перезапускаем Notepad++, идем в меню "Вид -> Список функций". Любуемся нашими метками справа от текста. Теперь, кликая дважды по их именам, можно быстро переходить к их объявлению в тексте.


Ну вот, в общем-то и все, что я хотел написать, рассказать.
Спасибо за внимание.

Приложение: yadisk (.xml, 6 Kb) - файл подсветки кода ассемблера Z80 "z80.xml".

Обновлено 06.05.2016 в 16:25 BlastOff

Метки: Нет Добавить / редактировать метки
Категории
3aRulem #16

Комментарии

  1. Аватар для Bedazzle
    Пробую скомпилить пример. Валится с ошибкой на инклуде, что не может найти
    sjasmplus-win32-1.07-rc7\examples\ZX-Spectrum\3color\3color.asm(9): error: [INCHOB] Error opening file: KillerBean2.$c

    решение: в скрипте компиляции меняем
    cd "$(project_full_name)"
    на
    cd "$(CURRENT_DIRECTORY)"

    Проблема номер два:
    открыть на редактирование файл "functionList.xml" из папки с установленным Notepad++.

    Нет такого файла в версии 6.3.2
    Более новые не предлагать, на больших файлах глючат с реплейсом.
    Обновлено 04.05.2016 в 23:20 Bedazzle
  2. Аватар для Black Cat / Era CG
    Ну ваще статья была довольно сыра, так как я все сам не очень хорошо успел протестировать.
    Первая проблема в том, что там получается 2-ные кавычки, и cd не срабатывает, лечится еще проще надо заменить во всех скриптах cd "$(project_full_name)" на cd $(project_full_name). То есть просто убрать лишние кавычки. А ваще принцип же в общем понятен, поэтому "кривые" скрипты можно уже переписать под себя.

    А насчет второй проблемы сказать ничего не могу, я просто не в курсе, как там (в более старых версиях) это реализуется и реализуется ли.

    Да и, если честно, все это очередной велосипед, причем не лучшего качества. Правда сам я пользуюсь пока им.

    P.S. Насчет второй проблемы попробую еще сейчас покопать.
  3. Аватар для Black Cat / Era CG
    Ну посмотрел я версию 6.3.2. Насколько я понял, там этой фичи нет просто.
  4. Аватар для Black Cat / Era CG
    Копипаста с оффсайта:
    Notepad++ 6.4 released

    29 June, 2013
    The major updates in v6.4 are new added Function List Panel, Find/Replace dialog statusbar and new user interface of Preferences dialog.
  5. Аватар для BlastOff
    Друзья, статью в блогах можно поправить. Информация востребована и должна быть достоверной. Пишите здесь что исправить и я актуализирую.
  6. Аватар для Black Cat / Era CG
    Ну тогда вот примерно такие скрипты я сейчас использую:
    // Скрипт компиляции проекта
    // Сохраняем все файлы
    npp_saveall
    // Сохраняем путь текущего редактируемого файла
    set current = $(FULL_CURRENT_PATH)
    // Переключаемся на основной файл проекта (должен быть открыт в 1-ой вкладке!)
    npp_switch $(#1)
    // Получаем полные имена файла меток и основного файла проекта
    set symbol_name = "$(CURRENT_DIRECTORY)\$(NAME_PART).sym"
    set project_full_name = "$(FULL_CURRENT_PATH)"
    // возвращаемся на ранее открытую вкладку
    // npp_switch $(current)
    // компилируем проект
    cd $(project_full_name)
    "<путь к SjASMPlus>\sjasmplus.exe" --fullpath --sym=$(symbol_name) $(project_full_name)
    // Скрипт запуска проекта
    // Сохраняем путь текущего редактируемого файла
    set current = $(FULL_CURRENT_PATH)
    // переключаемся на основной файл проекта (должен быть открыт в 1-ой вкладке!)
    npp_switch $(#1)
    // Получаем полное имя образа диска с откомпилированным проектом для запуска
    // (если вы компилируете в sna, поменяйте расширение на нужное)
    set image_name = "$(CURRENT_DIRECTORY)\$(NAME_PART).scl"
    // Возвращаемся на ранее открытую вкладку
    npp_switch $(current)
    // Запускаем откомпилированный проект
    "<путь к US>\unreal.exe" $(image_name)
    // Скрипт компиляции и запуска проекта
    // Сохраняем все файлы
    npp_saveall
    // Сохраняем путь текущего редактируемого файла
    set current = $(FULL_CURRENT_PATH)
    // Переключаемся на основной файл проекта (должен быть открыт в 1-ой вкладке!)
    npp_switch $(#1)
    // Получаем необходимые имена файлов
    set image_name = "$(CURRENT_DIRECTORY)\$(NAME_PART).trd"
    set symbol_name = "$(CURRENT_DIRECTORY)\$(NAME_PART).sym"
    set project_full_name = "$(FULL_CURRENT_PATH)"
    // Возвращаемся на ранее открытую вкладку
    npp_switch $(current)
    // Компилируем проект
    cd $(project_full_name)
    "<путь к SjASMPlus>\sjasmplus.exe" --fullpath --sym=$(symbol_name) $(project_full_name)
    // запускаем откомпилированный проект
    "<путь к US>\Unreal Spectrum\unreal.exe" $(image_name)

Трекбэков