Инструменты пользователя

Инструменты сайта


msx:maestro:maestro

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
msx:maestro:maestro [2020-11-04 14:02]
GreyWolf [Ссылки]
msx:maestro:maestro [2024-03-07 11:13] (текущий)
GreyWolf
Строка 1: Строка 1:
-====== Программное средство ​"Маэстро" ​======+====== Программное средство ​«Маэстро» ======
  
 +Автор: А.Б. Родионов \\
 +© МЭВЦ 1986–1988
  
-Страница на официальном сайте автора: [[http://​rodionov.info/​software.shtml#​MAESTRO_Intro|Программное средство "​МАЭСТРО"​ - аннотация]]+Программное средство (ПС) «Маэстро» предназначено для создания высокоэффективных ​и кратких программ на языке С для компьютеров [[msx:msx_1|MSX]] и [[msx:msx_2|MSX2]] и включает в себя такие средства программирования, как параллельные процессы, окна, ​работа с манипулятором «мышь»,​ специализированные методы доступа и обработки графических данных и многое другое. 
 +ПС «Маэстро» может быть использовано для разработки учебных программ, компьютерных игр, системных и прикладных программ ​и для других приложений.
  
 +С помощью ПС «Маэстро» автор создал [[msx:​maestro:​pac:​|]] и [[msx:​ar_games:​ar_games|эти игры]].
  
-Автор: А.Б. Родионов \\ +/* 
-© МЭВЦ ​1988 г.+Страница на официальном сайте автора:​ [[http://​rodionov.info/​software.shtml#​MAESTRO_Intro|Программное средство «МАЭСТРО» — аннотация]] 
 + 
 + 
 +[[http://​forum.rodionov.info:​8080/​forums/​msx.36/​|Форум на сайте автора]] 
 +*/ 
 + 
 +Основные главы: 
 +  * [[#​grplib|Графическая библиотека MSX для BDS C]] 
 +  * [[#​grplibm|Музыкальная библиотека]] 
 +  * [[#​utilites|Утилиты]] 
 + 
 +FIXME 
 +\\ Документация находится в процессе работы,​ описание изменений [[changes|здесь]]. 
 + 
 +~~TOC_HERE~~ 
 +~~TOC 1-3 wide~~ 
 + 
 + 
 +{{anchor:​grplib}} 
 +====== Графическая Библиотека MSX для BDS C ====== 
 +FIXME 
 + 
 +{{anchor:​grplib_disk}} 
 +Графическая Библиотека MSX для BDS C версия 3.05 
 +\\ MSX Graphic Library for BDS C v3.05 
 + 
 +{{:​msx:​maestro:​devdisk_-_msx_graphic_lib_3.05.dsk|Образ диска с версией 3.05}} 
 + 
 +(C) МЭВЦ 1988 
 + 
 +**Аннотация** 
 +\\ В данном документе содержится описание применения библиотеки функций «MSX Graphic Library for BDS C» версии 3.02. Документ предназначен для разработчиков программного обеспечения на компьютерах MSX2 и MSX и содержит следующие разделы:​ 
 +  * [[#​grplib_n1|Назначение]] 
 +  * [[#​grplib_n2|Условия применения]] 
 +  * Описание функций 
 +    * [[#​GRPLIB1]] 
 +    * [[#​GRPLIB2]] 
 +    * [[#​GRPLIB3]] 
 +    * [[#​GRPLIB4]] 
 +    * [[#​GRPLIB5]] 
 +  * [[#​grplib_n4|Рекомендации по использованию и форматы данных]] 
 + 
 +«MSX Graphic Library for BDS C» является авторской разработкой ​А. Б. Родионова (Москва,​ 1986–1988). Оригинальная документация ведётся на английском языке для совместимости с оборудованием,​ не имеющим кириллических знакогенераторов и может быть поставлена по специальному заказу. По этой же причине англоязычными являются все комментарии в текстах программ и диалог,​ ведущийся утилитами ПС «МАЭСТРО». 
 + 
 +Данный документ не следует рассматривать как учебное пособие по компьютерам MSX и MSX2 — напротив он рассчитан на подготовленный программистов,​ знающих архитектуру этих компьютеров,​ но испытывающих затруднения в выборе инструментальных средств для разработки своих программ. 
 + 
 +{{anchor:​grplib_n1}} 
 +===== Назначение ===== 
 + 
 +«MSX Graphic Library for BDS C» (в дальнейшем именуемая просто «Библиотека») предназначена для программистов,​ использующих компилятор [[bds_c:​bds_c|]]. Библиотека разработана специально для MSX-машин. 
 +Она обеспечивает полный доступ ко всей аппаратуре [[msx:​msx_2|MSX2]] и [[msx:​msx_1|MSX]] (в дальнейшем именуемой [[msx:​msx_1|MSX1]]) из программ,​ написанных на языке С. Кроме обращений к стандартным функциям [[msx:​bios|BIOS]] и [[msx:​bios#​subrom|SubROM]] MSX, библиотека включает в себя ряд новых специальных функций и методов доступа,​ облегчающих программирование сложных и ресурсоёмких задач. 
 + 
 +Библиотека может быть использована для разработки учебных программ,​ компьютерных игр, системных и прикладных программ и для других применений. 
 + 
 +Библиотека включает в себя следующие подразделы:​ 
 +  * [[#​parallel_processes|параллельные процессы с циркулярной и линейной очередями,​ почтой и др.]]; 
 +  * базовые методы работы с манипулятором «мышь»;​ 
 +  * спрайтовое зеркало;​ 
 +  * специальные методы доступа;​ 
 +  * работа с прерываниями;​ 
 +  * [[#​movmap0()|работа с мэппером]];​ 
 +  * отладочные функции:​ 
 +    * ''​[[#​showpage()]]''​ 
 +    * ''​[[#​prtscrnt()]]''​ 
 +    * ''​[[#​PAUSE()]]''​ 
 +  * вспомогательные функции. 
 + 
 +  * [[#​disk-io-vram|дисковый ввод/​вывод для VRAM MSX2]]; 
 +  * блочные пересылки RAM → VRAM, VRAM → RAM, VRAM → VRAM. 
 + 
 +  * [[#​drawing_functions|функции для рисования точек, линий, блоков и пр.]]; 
 +  * [[#​output_characters_on_graphic_screen|вывод символов на графический экран]];​ 
 +  * [[#​text_menus_in_graphical_mode|текстовые меню в графическом режиме]];​ 
 +  * [[#​test_screen_functions|прямой доступ к текстовому экрану]];​ 
 +  * [[#​polling_special_keyboard_keys|опрос специальных клавиш клавиатуры]];​ 
 +  * работа с мышью;​ 
 + 
 +  * [[#​sprintes|спрайты (логический уровень)]];​ 
 +  * [[#​disks|доступ к оглавлению диска и его сортировка]];​ 
 +  * методы организации и выделения оперативной памяти;​ 
 +  * [[#​printer|копирование текстового и графического экранов на принтер]];​ 
 +  * [[#​tape|ввод/​вывод для магнитной ленты]];​ 
 +  * [[#​psg|работа со звуковым генератором MSX]]; 
 +  * сжатие/​расширение информации в памяти;​ 
 +  * [[#​rwsector()|доступ к диску по секторам]]. 
 + 
 +  * [[#​dtov()|загрузка знакоместного полиэкрана]];​ 
 +  * [[#​work_polyscreen|управление знакоместным полиэкраном]];​ 
 +  * [[#​graphics_text_windows|графические и текстовые окна для полиэкрана]];​ 
 +  * спрайты [[msx:​msx_1|MSX1]];​ 
 +  * [[#​direct_io_polyscreen|прямой ввод/​вывод для полиэкрана]]. 
 + 
 +{{anchor:​grplib_n2}} 
 +===== Условия применения ===== 
 + 
 +Для пользования Библиотекой необходим MSX-компьютер с оперативной памятью минимум 64 кбайт и минимум одним дисковым приводом. Программы,​ написанные с использованием Библиотеки и компилятора [[bds_c:​bds_c|]],​ могут быть рассчитаны и на «бездисковую» или «сетевую» конфигурацию объектной машины (при соответствующем их программировании) или на компьютер с дисками и другим объёмом как оперативной,​ так и видеопамяти. 
 + 
 +Большая часть функций Библиотеки может быть использована как для компьютеров [[msx:​msx_1|MSX1]],​ так и [[msx:​msx_2|MSX2]],​ но некоторые функции (указаны особо в описании) применимы ТОЛЬКО к MSX1 или ТОЛЬКО к MSX2. 
 + 
 +В частности,​ раздел библиотеки [[#​GRPLIB2]] содержит функции ТОЛЬКО для [[msx:​msx_2|MSX2]] и НЕ ДОЛЖЕН использоваться при написании программ для [[msx:​msx_1|MSX1]],​ а раздел [[#​GRPLIB5]] и заголовок ''​GRPMSX1.H''​ ДОЛЖНЫ быть подключены к программе,​ если она рассчитана на компьютер MSX с 16 кбайт видеопамяти и без [[msx:​bios#​subrom|SubROM]] (дополнительного 16-кбайтного расширения ПЗУ, обеспечивающего большинство функций [[msx:​msx_2|MSX2]] со 128 кбайт видеопамяти и энергонезависимой памятью для календаря,​ часов, пароля и т.п.). 
 + 
 +Абсолютно необходимым условием успешного применения функций библиотеки является знание программистом архитектуры и особенностей компьютеров [[msx:​msx_1|MSX1]] и [[msx:​msx_2|MSX2]],​ операционной системы [[msx:​dos:​|]] и основных принципов работы со знакоместной и битмэп-графикой. Кроме этого, совершенно необходимо знание языка Си и особенностей его конкретной реализации в системе [[bds_c:|]] (смотри {{:​bds_c:​bds_c_v1.50a_users_guide_addenda_jul83.pdf|C Compiler v1.5 Users Guide, Copyright (c) 1982 by Leor Zolman BD Software}}). 
 + 
 +Для нормальной работы большинства функций Библиотеки требуется выделение и инициализация специальной системной рабочей области памяти. Эта рабочая область выделяется автоматически при ОБЯЗАТЕЛЬНОМ включении в создаваемую программу одного из двух 
 +системных заголовков:​ 
 +|<code c>#​include GRPLIB0.H</​code>​|для MSX2| 
 +|<code c>#​include GRPMSX1.H</​code>​|для MSX1| 
 + 
 +ВНИМАНИЕ! Любой из этих заголовков резервирует рабочую область в External и для правильной работы библиотеки должен быть записан в качестве САМОГО ПЕРВОГО оператора Вашего файла с исходным текстом программы на Си. Иными словами,​ Ваши собственные глобальные переменные должны располагаться только ПОСЛЕ системной рабочей области (иметь бОльшие адреса памяти). Внутрь этих заголовков всегда автоматически включается заголовок ''​BDSCIO.H''​ ''​GRPMSX1.H''​ включает в себя автоматический вызов ''​GRPLIB0.H''​ и его собственные функции могут замещать некоторые другие функции разделов библиотеки ''​GRPLIB1''​…''​GRPLIB5''​. 
 + 
 + 
 +Переменные условной компиляции для заголовков 
 + 
 +Есть несколько специальных операторов для условной компиляции заголовков ''​.Н'',​ которые можно указывать перед их вызовом:​ 
 +  * <code c>#​define NO_FUNC /* используется в GRPMSX1.H */</​code>​ Используйте этот оператор,​ если вы компилируете и линкуете более, чем 1 исходный файл на Си. Этот оператор условной компиляции должен присутствовать во всех ваших файлах с исходными текстами кроме ОДНОГО во избежание повторных генераций функций с одинаковыми именами т.к. заголовок ''​GRPMSX1.H''​ содержит в себе определения и переопределения функций ''​GRPLIB0.H'',​ специфических для [[msx:​msx_1|MSX1]] и не использующих SUBROM и [[msx:​yamaha_v9938:​yamaha_v9938|VDP9938]]. 
 +  * <code c>#​define NO_TICKS /* используется в GRPMSX1.H */</​code>​ Создаётся пустая функция totick() { } если не предполагается использование параллельных процессов. Это экономит память. 
 +  * <code c>#​define NO_PUTSXY /​* используется в GRPMSX1.H */</​code>​ Не создаётся переопределение функции ''​[[#​putsxy()]]''​ для вывода символов на текстовой экран MSX1 с использованием BIOS вместо обращения к [[msx:​yamaha_v9938:​yamaha_v9938|VDP9938]] 
 +  * <code c>#​define NO_RTOVLW /​* используется в GRPMSX1.H */</​code>​ Не создаются переопределения функций _rtovlw() и _vtorlw() для работы через BIOIS вместо прямого обращения к VDP9938 
 +  * <code c>#​define NO_MOUSE /* используется в GRPMSX1.H */</​code>​ Не используется вызов SUBROM в totick() для работы с мышью даже если используется [[msx:​msx_2|MSX2]] 
 +  * <code c>#​define NO_PBUF /* используется в GRPMSX1.H и GRPLIB0.H */</​code>​ Не создаётся массив ''​_pbuf[32]''​ в ''​GRPLIB0.H''​ для работы с функцией ''​[[#​fmt()]]''​. Сама функция ''​[[#​fmt()]]''​ также будет недоступна. Это экономит память. 
 +  * <code c>#​define JOY2ONLY /* используется в GRPSTICK.H и GRPLIB0.H */</​code>​ Используется опрос джойстика только в порте 2. Функция ''​[[#​chkmouse()]]''​ недоступна. Это экономит память. 
 + 
 +Предупреждения 
 + 
 +ВНИМАНИЕ! Для правильной работы библиотечных функций системная рабочая область ДОЛЖНА находиться в диапазоне адресов 4000~C000 (страницы 1 и 2) - поэтому,​ если Ваша программа меньше,​ чем 0х4000, компилируйте и линкуйте её с параметрами ''​-е4000''​ как минимум. ​\\ Таким образом,​ компилятору ''​cc.com''​ и ликовщику ''​clink.com''​ задается явный адрес начала области External, где находятся служебные вызовы некоторых встроенных бибилиотечных функций,​ в частности,​ обращения к функциям BIOS, SUBROM и MEMORY MAPPER. Использование для External областей памяти выше 0xBFFF также является недопустимым. 
 + 
 +ВНИМАНИЕ! Кроме выделения рабочей области при помощи включения в Вашу программу стандартных заголовков GRPLIB0.H или GRPMSX1.H, для нормальной работы библиотечных функций требуется последующая ИНИЦИАЛИЗАЦИЯ этой рабочей области с помощью функции ''​[[#​grpini()]]''​ или ''​[[#​gameini()]]''/''​[[#​gameini2()]]''​. Если вы забудете вызвать одну из этих функций в  начале Вашей программы — вы можете получить НЕПРЕДСКАЗУЕМЫЕ РЕЗУЛЬТАТЫ! 
 + 
 +Пример 1. 
 +<code c> 
 +/​*+-----------------------------------------------------------+*/​ 
 +/*| -- Образец правильного выполнения требований для MSX2: -- |*/ 
 +/​*+-----------------------------------------------------------+*/​ 
 +#include grplib0.h /​* выделение системной рабочей области */ 
 + 
 +char     foo, foo2; /* глобальные переменные пользователя ​ */ 
 +unsigned bar, bar2; /* глобальные переменные пользователя ​ */ 
 + 
 +main() /* точка входа */ 
 +
 +  int zot, zot2; /* локальные переменные пользователя */ 
 +  grpini(); /* инициализация системной рабочей области */ 
 +  /* ниже используются библиотечные функции - см. описание */ 
 +  screen(5);​ 
 +  palette(0, 0, 0, 0); color(15, 0, 0); cls(); 
 +  . 
 +  . 
 +  . 
 +  zot=frotz(0);​ 
 +  . 
 +  . 
 +  . 
 +  EXIT /* выход в MSXDOS */ 
 +
 + 
 +int frotz(zap) 
 +int zap; 
 +
 +  ... 
 +
 +/* ------------------- Конец образца -------------------- */ 
 +</​code>​ 
 + 
 +Пример 2. 
 +<code с> 
 +.+---------------------------------------------------------+ 
 +.| ----- Образец задания на компиляцию и компоновку ------ | 
 +.+---------------------------------------------------------+ 
 +cc gro 
 +clink gro -f grplib4 grplib3 grplib2 grplib1 grpliba -e6000 
 +. -------------------- Конец образца ---------------------- 
 +</​code>​ 
 +Примечания:​ 
 +  * точка «.» может быть использована в [[msx:​dos:​|]] вместо ''​REM'';​ 
 +  * если в файле ''​GRO.CRL''​ (результат работы компилятора [[bds_c:​bds_c|]]) появляются функции с именами,​ такими же как и в файлах Библиотеки ''​GRPLIB4.CRL''​ … ''​GRPLIB1.CRL''​ — они заменяют соответствующие функции Библиотеки,​ так как находятся в командной строке ''​clink''​ ДО переключателя ''​-f''​ (см. [[bds_c:​bds_c|]] ''​clink''​) (этот приём используется для подключения функций пользователя вместо стандартных системных заглушек,​ находящихся в библиотеке (''​[[#​process1() … process9()]]'',​ ''​[[#​tickexit()]]''​ — ), а также для исключения нежелательных библиотечных функций,​ которые подключаются автоматически (путём написания заглушек пользователем));​ 
 +  * порядок следования библиотечных файлов по убыванию их номеров <​code>​… -f grplib5 grplib4 grplib3 grplib2 grplib1 grpliba …</​code>​ является существенным для ''​clink'',​ так как в противном случае ''​clink''​ не найдёт функции,​ на которые появятся отсылки «назад» (см. [[bds_c:​bds_c|]] ''​clink''​). 
 + 
 +===== GRPLIB1 ===== 
 + 
 +Раздел Библиотеки GRPLIB1 
 + 
 +==== Специальные функции ==== 
 + 
 +=== beep() === 
 +<code с> 
 +beep(n) 
 +char n; 
 +</​code>​ 
 +Подача звукового сигнала '​n'​ раз. 
 + 
 +=== errmsg() === 
 +<code с> 
 +char *errmsg(errnum) 
 +char errnum; 
 +</​code>​ 
 +Расширенная версия стандартной функции ''​errmsg()''​ из библиотеки [[bds_c:​bds_c|]]  
 +\\ !ПЕРЕОПРЕДЕЛЕНИЕ! 
 + 
 +=== _fataler() === 
 +<code с> 
 +_fataler(mode,​ msg1, msg2) 
 +char mode, *msg1, *msg2; 
 +</​code>​ 
 +Аварийный выход из программы в [[msx:​dos:​|]] с установкой (без установки) ''​Screen 0''​ и выдачей сообщения (сообщений). 
 + 
 +Значения ''​mode''​ 
 +|0|''​Screen 0''​ и вывод только ''​msg1''​| 
 +|1|''​Screen 0''​ и вывод «Sorry, fatal error detected» на 1-й строке и ''​msg1''​ на второй строке.| 
 +|2|''​Screen 0''​ и вывод «Sorry, fatal error detected» на 1-й строке,​ а на второй ''​msg1''​ и ''​msg2''​| 
 +|10|выводить ''​msg1''​ не устанавливая ''​Screen 0''​| 
 +|11|выводить «Sorry, fatal error detected» на 1-й строке и ''​msg1''​ на второй строке не устанавливая ''​Screen 0''​| 
 +|12|выводить «Sorry, fatal error detected» на 1-й строке,​ а на второй ''​msg1''​ и ''​msg2''​ не устанавливая ''​Screen 0''​| 
 +|13|выводить ''​msg1''​ и ''​msg2''​ не устанавливая ''​Screen 0''​| 
 + 
 +==== Управляющие функции ==== 
 + 
 +=== grpini() === 
 +<code c>​grpini()</​code>​ 
 +Инициализация рабочей области Библиотеки. 
 + 
 +Внимание! ПОЧТИ НИЧЕГО НЕ БУДЕТ РАБОТАТЬ,​ ЕСЛИ ВЫ ЗАБУДЕТЕ НАПИСАТЬ ''​grpini()''​ или ''​[[#​gameini()]]''​ / ''​[[#​gameini2()]]''​ В НАЧАЛЕ ВАШЕЙ ПРОГРАММЫ!!! 
 + 
 +=== screen() === 
 +<code c> 
 +screen(mode) 
 +char mode; 
 +</​code>​ 
 +Установить тип графического экрана:​ 
 +  * 0…8 для [[msx:​msx_2|MSX2]],​ 
 +  * 0…3 для [[msx:​msx_1|MSX1]]. 
 + 
 +Палитра не инициализируется. Используйте ''​[[#​paletini()]]'',​ если предполагается в дальнейшем использовать функции ''​[[#​paletv()]]''​ или ''​[[#​paletrst()]]''​. 
 + 
 +=== cls() === 
 +<code c> 
 +cls() 
 +</​code>​ 
 + 
 +//​только для MSX2// (см. ''​[[#​gameini()]]''​ для [[msx:​msx_1|MSX1]]) 
 + 
 +Очистка экрана. Применима к любому типу экрана 0…8. 
 + 
 +=== sprctl() === 
 +<code c> 
 +sprctl(size,​ magn, disp, mode) 
 +char size, magn, disp, mode; 
 +</​code>​ 
 + 
 +Инициализация и настройка механизма работы со спрайтами. Используйте специальные имена из файла ''​GRPLIB0.H''​ в качестве параметров этой функции:​ 
 +|''​size''​|''​SIZE_8''​ или ''​SIZE_16''​|размер 8 или 16 точек| 
 +|''​magn''​|''​MAGNIFIED''​ или ''​UNMAGNIFIED''​|увеличение в 2 раза| 
 +|''​disp''​|''​ENABLE''​ или ''​DISABLE''​|разрешение/​запрет| 
 +|''​mode''​|''​SINGLE''​ или ''​SIMULTANEOUS''​|вывода спрайтов на экран (режим вывода спрайтов) (см. ниже)| 
 + 
 +Если вы хотите оставить без изменения значения каких-либо параметров — пишите имя ''​NONE''​ 
 + 
 +''​mode''​ специфицирует механизм,​ используемый для управления спрайтами:​ 
 +  * ''​SINGLE''​ — каждое выполнение функции ''​[[#​sprite()]]''​ приводит к немедленной модификации участков VRAM, определяющих координаты и другие параметры,​ относящиеся к данному плану спрайта (Sprite Attribute Table модифицируется в специальной рабочей области библиотеки,​ называемой «спрайтовое зеркало» в RAM, после чего БЛОК этой области пересылается (отражается) в VRAM для одновременного изменения параметров ВСЕХ спрайтов,​ определённых одной функцией ''​[[#​sprite()]]''​). 
 +  * ''​SIMULTANEOUS''​ — функция ''​[[#​sprite()]]''​ модифицирует спрайтовое зеркало,​ но не пересылает блок данных в VRAM — эта операция выполняется специальным скрытым от пользователя процессом каждый «тик» таймера в функции ''​[[#​totick()]]''​ — диспетчере параллельных процессов. 
 +Этот скрытый процесс активируется только в случае задания ''​mode = SIMULTANEOUS''​ и пересылает каждый «тик» ​ВСЁ спрайтовое зеркало целиком из RAM в VRAM. Такой режим является более «мягким» и часто более эффективным для работы со спрайтами одновременно из нескольких параллельно выполняющихся процессов,​ но он постоянно занимает время процессора и делает лишние пересылки в ''​Screen 0''​. Поэтому по умолчанию ''​mode = SINGLE''​. 
 + 
 +Вы можете «мягко» переходить из SINGLE в SIMULTANEOUS и наоборот во время выполнения программы без потери данных в спрайтовом зеркале. Работа этого механизма не зависит от ''​[[#​TICKON]]''​ / ''​[[#​TICKOFF]]''​. 
 + 
 +=== clrspr() === 
 +<code c> 
 +clrspr() 
 +</​code>​ 
 +//​только для MSX2// 
 + 
 +Стирание всех спрайтов в VRAM и в спрайтовом зеркале. 
 + 
 +''​clrspr()''​ будет корректно работать только в том случае,​ если предварительно была вызвана функция ''​[[#​screen()]]''​ с параметром,​ отличным от нуля, а также ''​[[#​sprctl()]]''​ с определением размера спрайтов. 
 + 
 +=== paletini() === 
 + 
 +<code c> 
 +paletini() 
 +</​code>​ 
 +//​только для MSX2// 
 + 
 +Инициализация палитры и VRAM для палитры. Не забудьте вызвать эту функцию,​ если будете использовать ''​[[#​paletv()]]''​ или ''​[[#​paletrst()]]''​. 
 + 
 +Область сохранения для палитры может быть организована в разных областях VRAM в зависимости от того, какая страница VRAM была активна в момент использования ''​[[#​paletini()]]''​ — пожалуйста,​ будьте осторожны! (это одно из неудачных решений в [[msx:​bios#​subrom|SubROM]]). 
 + 
 + 
 +=== paletrst() === 
 +//​только для MSX2// 
 + 
 +<code c> 
 +paletrst() 
 +</​code>​ 
 + 
 +Восстановить палитру,​ запомненную в VRAM. 
 + 
 +=== paletv() === 
 + 
 +<code c> 
 +paletv(paletnum,​ r, g, b) 
 +int paletnum, r, g, b; 
 +</​code>​ 
 +//​только для MSX2// 
 + 
 +Установить цветовой код для палитры ''​paletnum''​. В случае отрицательного значения какого-либо параметра старое значение остаётся без изменения. Это стандартная [[msx:​bios#​subrom|SubROM]]-версия,​ работающая с областью сохранения палитр в VRAM. 
 + 
 +=== palette() === 
 + 
 +<code c> 
 +palette(paletnum,​ r, g, b) 
 +int paletnum, r, g, b; 
 +</​code>​ 
 +//​только для MSX2// 
 + 
 +То же самое, что и ''​[[#​paletv()]]'',​ но VRAM не используется для сохранения палитры. Область сохранения палитры организуется в рабочей области RAM Библиотеки. ''​[[#​paletini()]]''​ и ''​[[#​paletrst()]]''​ не работают с этой областью,​ поэтому Вам не надо их использовать,​ если вы работаете с ''​palette()''​. Область сохранения палитр в рабочей области Библиотеки обнуляется во время выполнения ''​[[#​grpini()]]''​ 
 + 
 +!!!Для работы с областью сохранения палитр в RAM!!! 
 + 
 +=== GETPLT() === 
 +<code c> 
 +GETPLT(paletnum,​ r, g, b) 
 +/* macro */ 
 +</​code>​ 
 +//​только для MSX2// 
 + 
 +Запись в ваши переменные r, g, и b текущих значений Красного,​ Зелёного и Синего для палитры ''​paletnum''​. 
 + 
 +!!!Для работы с областью сохранения палитр в RAM!!! 
 + 
 +=== paletrot() === 
 +<code c> 
 +paletrot(<​список палитр>,​ 255) 
 +char <​список палитр>;​ 
 +</​code>​ 
 +//​только для MSX2// 
 + 
 +«Вращение» влево палитр в списке палитр. Более мощный эквивалент «Colour Rotation» [[msx:​yamaha_painter:​yamaha_painter|Yamaha Painter]].  
 + 
 +255 — признак конца списка палитр. 
 + 
 +Примеры использования:​ 
 +  * <code c>​paletrot(1,​5,​3,​255);</​code>​ переписывает палитры:​ 3 → 5, 5 → 1, 1 → 3; 
 +  * <code c>​paletrot(4,​2,​7,​6,​1,​255);</​code>​ переписывает палитры:​ 1 → 6, 6 → 7, 7 → 2, 2 → 4, 4 → 1. 
 + !!!Для работы с областью сохранения палитр в RAM!!! 
 + 
 +=== paletblk() === 
 +<code c> 
 +paletblk() 
 +</​code>​ 
 +//​только для MSX2// 
 + 
 +Установить палитры 0…15 в (0, 0, 0) — чёрный цвет. 
 + 
 +!!!Для работы с областью сохранения палитр в RAM!!! 
 + 
 +=== color() === 
 + 
 +<code с> 
 +color(fg, bg, bd) 
 +int fg, bg, bd; 
 +</​code>​ 
 +Установить цвета экрана (номера палитр):​ 
 +  * ''​fg''​ — для переднего плана,  
 +  * ''​bg''​ — заднего плана,​ 
 +  * ''​bd''​ — бордюра. 
 + 
 +=== page() === 
 +<code c> 
 +page(display,​ active) 
 +int display, active; 
 +</​code>​ 
 +//​только для MSX2// 
 + 
 +Управление страницами VRAM для Screen 5…8. 
 + 
 +=== swpage() === 
 +<​code>​ 
 +char swpage() 
 +</​code>​ 
 +//​только для MSX2// 
 + 
 +Обмен (swap) страниц ''​active''​ и ''​display''​.  
 + 
 +Возвращает номер страницы ''​active''​ 
 + 
 +=== swpaged() === 
 + 
 +<code > 
 +char swpaged() 
 +</​code>​ 
 +//​только для MSX2// 
 + 
 +Обмен (swap) страниц ''​active''​ и ''​display''​ 
 + 
 +Возвращает номер страницы ''​display''​ 
 + 
 +=== showpage() === 
 +<code c> 
 +showpage(mode) 
 +char mode; 
 +</​code>​ 
 +Отладочная функция,​ которая обычно стандартно подключается к каждой программе и вызывается диспетчером параллельных процессов с параметром 0 (''​showpage(0)''​). В этом режиме функция проверяет нажатие клавиш <​key>​STOP</​key>​ и <​key>​SELECT</​key>​ и, если они нажаты,​ захватывает управление. После этого, нажатие функциональных клавиш <​key>​F1</​key>​...<​key>​F4</​key>​ даёт возможность визуально проверить состояние всех страниц VRAM с плавным просмотром каждой страницы при помощи клавиш курсора,​ <​key>​F5</​key>​ возвращает управление в прерванную программу,​ <​key>​STOP</​key>​ и <​key>​F5</​key>​ — возвращает управление [[msx:​dos:​|]] с выдачей статистики использования процессов и состояний почтовых ящиков. 
 + 
 +ВНИМАНИЕ! Для сокращения объёма уже отлаженной программы можно исключить эту функцию на этапе компоновки,​ написав в тексте вашей программы заглушку с тем же именем:​ 
 +<code c>​showpage() { }</​code>​ 
 +В этом случае она будет подключена к вашей программе вместо библиотечной функции ''​showpage()''​ (см. [[bds_c:​bds_c|]] ''​clink''​). 
 +Этот же метод можно использовать для исключения других нежелательных библиотечных функций,​ которые подключаются автоматически. Например,​ если вы не планируете использовать [[#​parallel_processes|параллельные процессы]] — напишите заглушку:​ 
 +<code c> 
 +totick() { } 
 +</​code>​ 
 +и диспетчер параллельных процессов не будет подключён к вашей программе. 
 + 
 +Функция ''​showpage()''​ может быть вызвана в вашей программе и в явном виде: 
 +  * ''​showpage(1)''​ захватит управление без проверки <​key>​STOP</​key>​ и <​key>​SELECT</​key>,​ 
 +  * ''​showpage(2)''​ завершит выполнение программы с выдачей статистики по параллельным процессам. 
 + 
 +=== clrbuf() === 
 +<code c> 
 +clrbuf() 
 +</​code>​ 
 +Очистка буфера клавиатуры. 
 + 
 +=== backup() === 
 +<code c> 
 +backup() 
 +</​code>​ 
 +Восстановление параметров экрана из [[msx:​rtc#​block2|энерго-независимой памяти]] для [[msx:​msx_2|MSX2]] или стандартных значений из файла ''​GRPMSX1.H''​ для [[msx:​msx_1|MSX1]]. 
 + 
 + 
 +{{anchor:​parallel_processes}} 
 +==== Параллельные процессы ==== 
 + 
 +=== totick() === 
 +<code c> 
 +totick() 
 +</​code>​ 
 +Диспетчер параллельных процессов. 
 + 
 +Алгоритм работы:​ 
 +\\ Независимо от того, был или нет «тик» таймера,​ вызывается функция пользователя с именем ''​[[#​process0()]]''​. В случае,​ если с момента предыдущего вызова ''​totick()''​ таймер не изменил своего значения (анализируется jiffy) — управление возвращается к вызвавшей ''​totick()''​ функции. Если же значение таймера изменилось (прошёл квант времени,​ равный как минимум одному «тику»):​ 
 +  * вызывается функция с именем ''​[[#​showpage()]]'',​ 
 +  * механизм работы со спрайтовым зеркалом (если активирован),​ 
 +  * механизм отслеживания абсолютных координат манипулятора «мышь» для MSX2 (если активирован,​ 
 +  * процесс пользователя с именем ''​[[#​tickexit()]]'',​ 
 +  * диспетчер циркулярной очереди процессов с именем ''​[[#​_calproc()]]'',​ который вызывает один из процессов пользователя с именами ''​[[#​process1() … process9()]]''​ (по одному на каждый «тик»). 
 +После завершения выполнения всех вызванных функций,​ управление возвращается к вызвавшей ''​totick()''​ функции. 
 + 
 +Процессы пользователя ''​[[#​process0()]]'',​ ''​[[#​tickexit()]]''​ и ''​[[#​process1() … process9()]]''​ могут сами обращаться к ''​totick()''​ во время их выполнения,​ так как в это время они блокируются диспетчером от нежелательной вложенности вызовов. 
 + 
 +Обращения к ''​totick()''​ встроены в большинство стандартных функций Библиотеки и, поэтому,​ в программах,​ интенсивно использующих библиотечные функции,​ обращение к диспетчеру происходит с достаточной частотой для нормирования вызова процессов пользователя по каждому кванту таймера. Если же программа пользователя не обращается к диспетчеру достаточно часто (например,​ используется много арифметических вычислений) — для нормальной работы диспетчера рекомендуется вставлять обращения к нему в тексте программы в явном виде: 
 +<code c> 
 +totick(); 
 +</​code>​ 
 +Функции ''​[[#​process0()]]'',​ ''​[[#​tickexit()]]''​ и ''​[[#​process1() … process9()]]''​ содержатся в Библиотеке в виде заглушек и автоматически заменяются на функции пользователя с такими же именами,​ если пользователь описал их в своей программе. Эта замена происходит на этапе компоновки программы при помощи ''​clink''​. 
 + 
 +=== TICKON === 
 +<code c> 
 +TICKON 
 +/* macro */ 
 +</​code>​ 
 +Активация механизма псевдо–прерываний — разрешение вызова функций ''​[[#​process0()]]'',​ ''​[[#​tickexit()]]''​ и ''​[[#​process1() … process9()]]''​ диспетчером параллельных процессов ''​[[#​totick()]]''​ 
 + 
 +=== TICKOFF === 
 +<code c> 
 +TICKOFF 
 +/* macro */ 
 +</​code>​ 
 +Деактивация механизма псевдо–прерываний — запрет вызова функций ''​[[#​process0()]]'',​ ''​[[#​tickexit()]]''​ и ''​[[#​process1() … process9()]]''​ 
 + 
 +Установлен по умолчанию после выполнения ''​[[#​grpini()]]''​ 
 + 
 +=== TICKSTOP === 
 + 
 +<code c> 
 +TICKSTOP 
 +/* macro */ 
 +</​code>​ 
 +Временная приостановка механизма псевдо-прерываний без изменения состояния ''​[[#​TICKON]]''​ / ''​[[#​TICKOFF]]''​ 
 + 
 +Используется обычно в совокупности с ''​[[#​TICKSTART]]''​ 
 + 
 +=== TICKSTART === 
 +<code с> 
 +TICKSTART 
 +/* macro */ 
 +</​code>​ 
 +Отмена ''​[[#​TICKSTOP]]''​ без изменения состояния ''​[[#​TICKON]]''​ / ''​[[#​TICKOFF]]''​ 
 + 
 +Установлен по умолчанию после выполнения ''​[[#​grpini()]]''​ 
 + 
 +=== MAXPROCS() === 
 +<code с> 
 +MAXPROCS(n) 
 +/* macro */ 
 +</​code>​ 
 +Определение максимального количества процессов в циркулярной очереди ''​[[#​process1() … process9()]]''​ (длины очереди). %% 0 ≤ n ≤ 9 %%. По умолчанию — 0 (ни одного). Вы можете изменять длину циркулярной очереди во время выполнения вашей программы. 
 +Следует заметить,​ что частота вызова каждой отдельной функции ''​[[#​process1() … process9()]]''​ обратно пропорциональна числу процессов в циркулярной очереди,​ определённому при помощи ''​MAXPROCS()''​. 
 + 
 +=== ACTIVATE() === 
 +<code c> 
 +ACTIVATE(pnum) 
 +/* macro */ 
 +</​code>​ 
 +Активировать процесс ''​pnum''​ (0…9). 
 + 
 +Внимание! Процесс может быть активирован,​ но, тем не менее, никогда не вызван,​ если его номер больше,​ чем число процессов,​ определённых при помощи ''​[[#​MAXPROCS()]]''​. 
 + 
 +По умолчанию,​ после выполнения ''​[[#​grpini()]]''​ все процессы находятся в «активном» состоянии,​ но не выполняются,​ так как ''​MAXPROCS(0)''​. 
 + 
 +=== DEACTIVATE() === 
 +<code c> 
 +DEACTIVATE(pnum) 
 +/* macro */ 
 +</​code>​ 
 +Деактивировать процесс ''​pnum''​ (0…9). Процесс переводится в «пассивное» состояние — следующий процесс в циркулярной очереди анализируется на «активность». 
 + 
 +=== PUTMAIL() === 
 +<code c> 
 +PUTMAIL(boxnum,​message,​who) 
 +/* macro */ 
 +</​code>​ 
 +Имеется 16 «простых» почтовых ящиков (0…15) без очередей. Вы можете положить в почтовый ящик ''​boxnum''​ (char) сообщение ''​message''​ (integer) и сообщить,​ кто его послал ''​who''​ (integer) другому (другим) процессам,​ которые могут проверять этот почтовый ящик. ''​PUTMAIL()''​ является макросом,​ возвращающим значение OK (0), если сообщение успешно положено в почтовый ящик, или ERROR (-1) в случае,​ если там уже что–то лежит и ещё никем не получено при помощи ''​[[#​GETMAIL()]]''​ (''​message''​ ≠ 0). 
 + 
 +Таким образом,​ 
 +<code c> 
 +if (PUTMAIL(…) == ERROR) <​ждите и пробуйте снова>​ 
 +</​code>​ 
 +Конечно,​ в рамках Z80 и [[bds_c:​bds_c|]],​ ''​message''​ может быть, в том числе, и указателем на какие-либо данные или структуры. 
 + 
 +В простых случаях,​ вы можете использовать почтовые ящики непосредственно,​ так как они имеют стандартные имена ''​MAILBOX(0) … MAILBOX(15)''​ (номер почтового ящика может быть переменной).  
 +Примеры:​ 
 +  * <code c>​MAILBOX(5)=TRUE;</​code>​ 
 +  * <code c>if (MAILBOX(i) == 61) { ... }</​code>​ 
 + 
 +=== GETMAIL() === 
 +<code c> 
 +GETMAIL(boxnum,​messvar,​sendvar) 
 +/* macro */ 
 +</​code>​ 
 +Забрать сообщение из почтового ящика ''​boxnum''​ в переменную ''​messvar'',​ а идентификатор пославшего — в переменную ''​sendvar''​. 
 +\\ ''​messvar''​ будет равна 0, если в ящике ничего нет. ''​GETMAIL()''​ устанавливает в 0 значение почтового ящика после того, как заберёт оттуда сообщение. 
 + 
 +=== ABANDONWINDOW === 
 +<code c> 
 +ABANDONWINDOW 
 +/* macro */ 
 +</​code>​ 
 +Специальный тип почты, заставляющий последнее меню, открытое при помощи ''​[[#​windsel()]]''​ прекратить ожидание выбора альтернативы. 
 + 
 +=== tickexit() === 
 +<code c> 
 +tickexit() 
 +</​code>​ 
 +Системная заглушка для процесса пользователя. Напишите функцию с таким же именем — и она будет подставлена ''​clink''​ на этапе компоновки вместо заглушки. 
 + 
 +Эта функция будет выполняться каждый «тик» таймера (при достаточном количестве обращений к ''​[[#​totick()]]''​). 
 + 
 +К ''​tickexit()''​ неприменимы операции ''​[[#​ACTIVATE]]''​ / ''​[[#​DEACTIVATE]]''​ — её выполнение зависит только от ''​[[#​TICKON]]''​ / ''​[[#​TICKOFF]]''​ и ''​[[#​TICKSTART]]''​ / ''​[[#​TICKSTOP]]''​. 
 + 
 +Выполняется только в состоянии ''​[[#​TICKON]]''​ и ''​[[#​TICKSTART]]''​ !!! 
 + 
 +=== process1() … process9() === 
 +<​code>​ 
 +process1() ... process9() 
 +</​code>​ 
 +Имена системных заглушек для процессов пользователя,​ находящихся в циркулярной очереди и получающих управление по одному на каждый «тик». К этим процессам применимы операции ''​[[#​ACTIVATE]]''​ / ''​[[#​DEACTIVATE]]''​. 
 + 
 +Выполняются только в состоянии ''​[[#​TICKON]]''​ и ''​[[#​TICKSTART]]''​ !!! 
 + 
 +=== process0() === 
 +<code c> 
 +process0() 
 +</​code>​ 
 +Имя системной заглушки для самого приоритетного процесса пользователя не квантизируемого по «тикам» таймера — он получает управление каждый раз, когда вызывается ''​[[#​totick()]]''​ вне зависимости от того был «тик» таймера или нет. 
 + 
 +К этому процессу применимы операции ''​[[#​ACTIVATE]]''​ / ''​[[#​DEACTIVATE]]''​. 
 + 
 +Выполняются только в состоянии ''​[[#​TICKON]]''​ и ''​[[#​TICKSTART]]''​ !!! 
 + 
 +=== P_COUNT0 … P_COUNT9 === 
 +<​code>​ 
 +P_COUNT0 ... P_COUNT9 
 +</​code>​ 
 +Системные переменные. 
 + 
 +10 внутренних счётчиков вызовов для процессов 0…9 (unsigned). 
 + 
 +Каждый счётчик увеличивается на 1 при каждом новом вызове соответствующего процесса диспетчером. Вы можете использовать их для управления частотой исполнения процесса внутри него самого,​ например,​ следующим образом:​ 
 +<code c> 
 +main() 
 +
 +  ... 
 +  MAXPROCS(2) 
 +  TICKON 
 +  ... 
 +
 + 
 +process1() 
 +
 +  if (P_COUNT1 % 4) return; 
 +  ... 
 +
 +</​code>​ 
 +В этом примере ''​process1()''​ будет фактически выполняться 1 раз за каждые 8 «тиков» таймера вместо обычного выполнения каждый второй «тик». 
 + 
 +=== T_COUNT === 
 +<code c> 
 +T_COUNT 
 +</​code>​ 
 +Системная переменная. 
 + 
 +То же самое, что и ''​[[#​P_COUNT]]'',​ но для ''​[[#​tickexit()]]''​. 
 + 
 + 
 +==== Другие базовые функции ==== 
 + 
 +=== waitvdp() === 
 +<code c> 
 +waitvdp() 
 +</​code>​ 
 + 
 +Ожидание обнуления бита 0 (Command Execution) статусного регистра 2 [[msx:​yamaha_v9938:​yamaha_v9938|V9938]] для MSX2. Количество «тиков» ожидания записывается в переменную ''​_waitvdp''​ (unsigned) в рабочей области библиотеки. 
 + 
 +=== drowse() === 
 +<code c> 
 +drowse(t) 
 +unsigned t; 
 +</​code>​ 
 +«Дремать» — пропустить ''​t''​ «тиков» таймера вызывая ''​[[#​totick()]]''​. 
 + 
 +Эту функцию удобно использовать для задания временных интервалов мигания надписей на экране,​ мультипликации и пр. 
 + 
 +=== vpoke() === 
 +<code c> 
 +vpoke(addr, byte) 
 +unsigned addr; 
 +char byte; 
 +</​code>​ 
 +Записать байт в VRAM. 
 + 
 +=== vpeek() === 
 +<code c> 
 +char vpeek(addr) 
 +unsigned addr; 
 +</​code>​ 
 +Прочитать байт из VRAM. 
 + 
 +=== writevdp() === 
 +<code c> 
 +writevdp(reg,​ byte) 
 +char reg, byte; 
 +</​code>​ 
 +Записать байт в регистр VDP и в соответствующий теневой регистр в RAM. 
 + 
 +=== readvdp() === 
 + 
 +<code c> 
 +char readvdp(reg) 
 +char reg; 
 +</​code>​ 
 +Прочитать регистр VDP (из теневого регистра RAM). 
 + 
 +=== vdpstat() === 
 +<code c> 
 +char vdpstat(statreg) 
 +char statreg; 
 +</​code>​ 
 +Прочитать регистр статуса VDP (0…9 для [[msx:​yamaha_v9938:​yamaha_v9938|V9938]]). 
 + 
 +=== stick() === 
 +<code c> 
 +char stick(stick_no) 
 +char stick_no; 
 +</​code>​ 
 +Получить направление (0…8) с джойстика (0…2). 
 + 
 +=== trig() === 
 +<code c> 
 +char trig(trig_no) 
 +char trig_no; 
 +</​code>​ 
 +Получить статус (TRUE/​FALSE) кнопки триггера (0…4). 
 + 
 +=== pad() === 
 +<code c> 
 +char pad(pad_no) 
 +char pad_no; 
 +</​code>​ 
 +Читать Paddle, Light Pen, Mouse, Track Ball. 
 + 
 +=== getjiffy() === 
 +<code c> 
 +int getjiffy() 
 +</​code>​ 
 +Получить значение JIFFY MSX (2-байтовый счётчик,​ увеличивающийся каждый «тик» (1/60 или 1/50 секунды в зависимости от системы кодирования цвета NTSC/​PAL). 
 + 
 +=== *deblank() === 
 +<code c> 
 +char *deblank(to_str,​from_str) 
 +char *to_str,​*from_str;​ 
 +</​code>​ 
 +Перепись строки ''​from_str''​ в строку ''​to_str''​ с исключением всех пробелов и знаков табуляции. Возвращается указатель на строку ''​to_str''​. 
 + 
 +=== *upshift() === 
 +<code c> 
 +char *upshift(str) 
 +char *str; 
 +</​code>​ 
 +Приведение строки ''​str''​ к заглавным буквам ASCII. Используется функция ''​[[#​toupper()]]''​. Возвращается указатель на строку ''​str''​. 
 + 
 +=== _rtovlw() === 
 +<code c> 
 +_rtovlw(radr,​vadr,​len) 
 +unsigned radr,​vadr,​len;​ 
 +</​code>​ 
 +Пересылка данных RAM → VRAM для нижних 64 кбайт VRAM. 
 + 
 +В отличие от ''​[[#​rtovlow()]]''​ внутри функции не вызывается ''​[[#​totick()]]''​. 
 + 
 +=== _vtorlw() === 
 +<code c> 
 +_vtorlw(vadr,​radr,​len) 
 +unsigned radr,​vadr,​len;​ 
 +</​code>​ 
 +Пересылка данных VRAM → RAM для нижних 64 кбайт VRAM. 
 + 
 +В отличие от ''​[[#​vtorlow()]]''​ внутри функции не вызывается ''​[[#​totick()]]''​. 
 + 
 +=== movmap0() === 
 +<code c> 
 +char movmap0(source,​dest,​count,​mapper_page) 
 +unsigned source,​dest,​count;​ 
 +char mapper_page;​ 
 +</​code>​ 
 +Обмен данными с RAM в [[msx:​ram:​ram#​mapper|Memory Mapper]]. Во время работы функции вместо текущей страницы 0 мэппированного слота RAM временно подставляется страница ''​mapper_page''​ из [[msx:​ram:​ram#​mapper|Memory Mapper]]. 
 + 
 +Пересылка осуществляется с адреса ''​source''​ в адрес ''​dest''​ длиной ''​count''​ (1…0x4000) байтов. Во время пересылки,​ адреса 0…0x3FFF принадлежат подставленной странице [[msx:​ram:​ram#​mapper|Memory Mapper]], а 0x4000…0xFFFF — текущей конфигурации RAM. После пересылки для нулевой страницы мэппированного слота восстанавливается текущая конфигурация RAM и управление возвращается в вызывающую программу. Таким образом,​ вы можете записывать/​читать данные из любой страницы [[msx:​ram:​ram#​mapper|Memory Mapper]] блоками не более 16 Кбайт за одно выполнение ''​movmap0()'',​ a также осуществлять пересылки внутри подставленной страницы,​ если и ''​source''​ и  ''​dest''​ находятся в пределах 0…0x3FFF. 
 + 
 +Во время выполнения ''​[[#​grpini()]]''​ системной переменной ''​[[#​MEMORY_MAPPER]]''​ присваивается значение TRUE/FALSE в зависимости от того, оснащён ли данный компьютер аппаратурой [[msx:​ram:​ram#​mapper|Memory Mapper]]. Вы можете анализировать эту переменную в своей программе и, в зависимости от этого, так или иначе строить алгоритм работы программы:​ 
 +<code c> 
 +if (MEMORY_MAPPER) { ... } 
 +else { ... } 
 +</​code>​ 
 +Кроме того, ''​[[#​grpini()]]''​ создаёт специальный байт ''​_mapmask'',​ для указания,​ какие страницы [[msx:​ram:​ram#​mapper|Memory Mapper]] активны в данном компьютере. Например:​ значение 0xF8 (1111 1000) для ''​_mapmask''​ означает,​ что в [[msx:​ram:​ram#​mapper|Memory Mapper]] активны только 3 бита (нули) и, следовательно,​ Вам доступны 8 страниц RAM по 16 кбайт каждая. 
 + 
 +Дополнительно,​ функция ''​movmap0()''​ возвращает следующие коды: 
 +  * 0 — OK 
 +  * 1 — [[msx:​ram:​ram#​mapper|Memory Mapper]] не найден 
 +  * 2 — не найден RAM по адресу ''​dest''​ 
 + 
 +В случае выполнения функции с кодом возврата,​ отличным от 0 — системная переменная ''​[[#​MEMORY_MAPPER]]''​ автоматически устанавливается в FALSE. 
 + 
 +=== geteda() === 
 +<code c> 
 +unsigned geteda(dataname) 
 +char *dataname;​ 
 +</​code>​ 
 +Получение адреса данных,​ прикомпонованых к программе при помощи утилиты [[#​EDL.COM|Extra Data Linker (EDL.COM)]]. 
 + 
 +Любые данные (экраны,​ библитеки знакомест,​ таблицы и пр.), могут быть пркомпонованы к вашему COM-файлу при помощи [[#​EDL.COM|EDL]] с тем, чтобы быть использованными во время работы программы без дополнительных обращений к диску. Функция geteda() возвращает адрес таких данных,​ прикомпонованых после области External, или 0, если данные не найдены. Каждый прикомпонованый набор данных имеет 15-байтовый заголовок,​ который,​ в свою очередь,​ содержит 2-байтовое слово с длиной набора данных + 15 (длина заголовка) и 13-байтовую строку с именем набора данных,​ оканчивающуюся двоичным нулём. Так как за одно выполнение [#​EDL.COM|EDL]] к COM-файлу может быть прикомпонован более чем один набор данных,​ эти 13-байтовые строки служат идентификаторами каждого набора данных. 
 + 
 +''​[[#​geteda()]]''​ ищет набор данных с именем ''​dataname''​ (имя предварительно подвергается операциям upshift и deblank) и возвращает точный адрес данных (адрес первого байта после заголовка) или 0. 
 + 
 +Длину прикомпонованых данных можно узнать,​ прочитав слово (2 байта) по адресу ''​geteda()-15''​. 
 + 
 +Примечание. В качестве имён данных [[#​EDL.COM|Extra Data Linker]] использует имена файлов,​ сообщаемых ему в командной строке. При этом, префикс дисковода (если присутствует) не попадает в имя набора данных,​ а суффикс (.<​расширение>​) является неотъемлемой его частью. Таким образом,​ ''​dataname'',​ как параметр функции,​ должен включать в себя суффикс имени файла, указанного в командной строке [[#​EDL.COM|EDL]] (если файл имеет суффикс). 
 + 
 +=== geteda2() === 
 +<code c> 
 +unsigned geteda2(dataname,​base) 
 +unsigned dataname,​base;​ 
 +</​code>​ 
 +То же самое, что и ''​[[#​geteda()]]'',​ но набор данных может быть прикомпонован начиная с адреса ''​base''​. 
 + 
 +[[#​EDL.COM|EDL]] версии 1.01 и выше может прикомпоновывать данные не только к концу области External (''​-f''​),​ но и к концу кодовой части программы (''​-c''​) или к началу области External (''​-e''​). 
 + 
 +Поэтому вы можете вызывать ''​geteda2()''​ следующим образом:​ 
 +  * ''​geteda2(<​file>,​codend())''​ для ''​-c''​ (конец кода),​ 
 +  * ''​geteda2(<​file>,​extrns())''​ для ''​-e''​ (начало External),​ 
 +  * ''​geteda2(<​file>,​endext())''​ для ''​-f''​ (конец External «free RAM»). 
 + 
 +Образец использования geteda2():​ 
 +<code c> 
 +char *p,​*c_end;​ 
 +if (!(p=geteda2("​data",​c_end=codend()))) swapin("​data",​p=c_end);​ 
 +</​code>​ 
 +В этом примере при помощи ''​geteda2()''​ проверяется наличие файла ''​data''​ (без суффикса),​ прикомпонованого к концу кодовой области программы (был использован переключатель ''​-c''​ [[#​EDL.COM|EDL]]),​ и, в случае его наличия,​ указателю p присваивается адрес начала данных файла ''​data''​. В противном случае (если p = 0) — файл загружается в память с диска (в обоих случаях предполагается,​ что между концом кодовой части программы и началом области External существует достаточно места для размещения файла ''​data''​). 
 +Этот приём удобно использовать при написании программы в том случае,​ когда данные,​ используемые программой,​ могут претерпевать частые изменения в процессе отладки и подготавливаются каким-либо специальным редактором (например,​ графика,​ разрабатываемая при помощи Pattern Composer). Таким образом,​ во время отладки данные могут просто загружаться с диска без использования [[#​EDL.COM|EDL]],​ а в готовой программе — составлять единое целое с COM-файлом,​ прикомпонованые к ней без перекомпиляции программы следующим образом (см. описание утилиты [[#​EDL.COM|Extra Data Linker]]):​ 
 + 
 +<​code>​ 
 +A>edl prog progdat -c data 
 +</​code>​ 
 +Функции ''​[[#​geteda()]]''​ и ''​geteda2()''​ удобно использовать вместе с функцией ''​[[#​expand()]]''​. 
 + 
 +=== setdi() === 
 +<code c> 
 +setdi() 
 +</​code>​ 
 +При помощи ''​setdi()''​ вы можете подавить все команды EI (Еnable Interrupt) в кодовой части Библиотеки,​ которая выполняет обращениe к [[msx:​bios|BIOS]] / [[msx:​bios#​subrom|SubROM]] и, поэтому,​ чаще всего будете получать управление обратно в режиме DI (Disable Interrupt) — это зависит от работы конкретных точек входа [[msx:​bios|BIOS]] / [[msx:​bios#​subrom|SubROM]]. 
 + 
 +=== setei() === 
 +<code c> 
 +setei() 
 +</​code>​ 
 +Функция,​ обратная ''​[[#​setdi()]]''​ — включает все команды EI (Enable Interrupt) в кодовой части Библиотеки,​ которые могли быть выключены ''​[[#​setdi()]]''​. 
 + 
 +Гарантируется возврат управления в вашу программу в режиме EI (Enable Interrupt). Этот режим установлен по умолчанию,​ так как в противном случае многие системные механизмы MSX не будут работать в отсутствие прерываний. 
 + 
 +=== inith() === 
 +<code c> 
 +char *inith(addr,​str) 
 +char *addr,​*str;​ 
 +</​code>​ 
 +Инициализация памяти при помощи шестнадцатеричных цифр, записанных в виде литеральной строки. Все не-шестнадцатеричные символы игнорируются. 
 + 
 +Например:​ 
 +<code c> 
 +inith(buf,"​FF A|B.01 v 2"); 
 +</​code>​ 
 +инициализирует ''​buf''​ как FFAB0120. Обратите внимание на то, что последний нуль появляется из-за нечётного количества шестнадцатеричных символов в исходной строке. 
 +Возвращает указатель на <​последний записанный байт>​ + 1, то есть адрес следующего «свободного» байта. 
 + 
 +=== expand() === 
 +<code c> 
 +unsigned expand(from,​ to) 
 +unsigned from, to; 
 +</​code>​ 
 +Экспандировать (расширить,​ развернуть) данные,​ компрессированные (сжатые) при помощи утилиты [[#​FCX.COM]] и находящиеся по адресу ''​from''​. 
 + 
 +Экспандированные данные разместить в памяти по адресу ''​to''​. 
 + 
 +Возвращает длину экспандированных данных. 
 + 
 +=== getparm() === 
 +<code c> 
 +unsigned getparm(n_arg,​ arg0_adr) 
 +unsigned n, *arg0_adr;​ 
 +</​code>​ 
 +Возвратить параметр ''​n_arg''​ (0…n) из списка параметров функции с переменным (неопределённым) числом аргументов. 
 + 
 +Пример:​ 
 +<code c> 
 +main() 
 +
 +  foo(0, 1, 2, "​text"​);​ 
 +
 + 
 +  foo(args) 
 +  unsigned args; 
 +
 +  printf("​%d %s",​getparm(2,​ &args), getparm(3, &​args));​ 
 +
 +</​code>​ 
 +В результате выполнения этой программы будет выведено на экран:​ 
 +<​code>​ 
 +2 text 
 +</​code>​ 
 +__//​Примечание://​__ альтернативным (и более быстрым) способом извлечения аргументов по номеру является использование макросов ''​[[#​VARPARMS()]]''​ и ''​[[#​PARM()]]''​. 
 + 
 +===== GRPLIB2 ===== 
 + 
 +Раздел Библиотеки GRPLIB2 (ТОЛЬКО ДЛЯ MSX2) 
 + 
 +==== Дисковые функции MSX2 (SCREEN 5…8) ==== 
 + 
 +=== dtov() === 
 +<code c> 
 +dtov(fname, dx, dy, dir, lop) 
 +char *fname, dir, lop; 
 +unsigned dx, dy; 
 +</​code>​ 
 +Загрузка в VRAM файла ''​fname''​. Файл загружается начиная с координат ''​dx'',''​dy''​ VRAM с направлением передачи данных ''​dir''​ и применением логической операции ''​lop''​. Размер файла (ширина и высота в точках) записывается в первых двух словах этого файла — это формат оператора ''​COPY''​ [[msx:​basic:​basic#​v2x}|MSX BASIC 2.0]] и «Data» [[msx:​yamaha_painter:​yamaha_painter|Yamaha Painter]]. Используйте специальные ключевые слова из стандартного заголовка ''​GRPLIB0.H'':​ 
 +  * для ''​dir''​ 
 +    * ''​R_D''​ — вправо вниз, 
 +    * ''​L_D''​ — влево вниз, 
 +    * ''​R_U''​ — вправо вверх,​ 
 +    * ''​L_U''​ — влево вверх;​ 
 +  * для ''​lop''​ без прозрачного цвета:​ 
 +    * ''​PSET''​ или ''​IMP'',​ 
 +    * ''​AND'',​ 
 +    * ''​OR'',​ 
 +    * ''​XOR''​ или ''​EOR'',​ 
 +    * ''​NOT''​ или ''​PRESET'';​ 
 +  * для ''​lop''​ с прозрачным цветом:​ 
 +    * ''​TPSET''​ или ''​TIMP'',​ 
 +    * ''​TAND'',​ 
 +    * ''​TOR'',​ 
 +    * ''​TXOR''​ или ''​TEOR'',​ 
 +    * ''​TNOT''​ или ''​TPRESET''​. 
 + 
 +ВНИМАНИЕ! Эта функция использует точку входа в [[msx:​bios#​subrom|SubROM]],​ которая работает некорректно — а именно,​ затирает вторую страницу RAM (0x8000…0xBFFF). Будьте осторожны! 
 + 
 +=== vtod() === 
 +<code c> 
 +vtod(fname, sx, sy, width, height, dir, lop) 
 +char *fname, dir, lop; 
 +unsigned dx, dy, width, height; 
 +</​code>​ 
 +Запись на диск в файл ''​fname''​ информации из VRAM. Файл записывается начиная с ''​sx'',''​sy''​ VRAM с направлением передачи данных ''​dir''​ и применением логической операции ''​lop''​. 
 +Ширина прямоугольного блока данных из VRAM задаётся ''​width'',​ высота — ''​height''​ (в точках). Используйте специальные ключевые слова из стандартного заголовка GRPLIB0.H для ''​dir''​ и ''​lop''​ (см. ''​[[#​dtov()]]''​). 
 + 
 +ВНИМАНИЕ! Эта функция использует точку входа в [[msx:​bios#​subrom|SubROM]],​ которая работает некорректно — а именно,​ затирает вторую страницу RAM (0x8000…0xBFFF). Будьте осторожны! 
 + 
 +=== dtor() === 
 +<code c> 
 +dtor(fname,​start_adr,​ end_adr) 
 +char *fname; 
 +unsigned start_adr, end_adr; 
 +</​code>​ 
 +Загрузка файла ''​fname''​ в RAM. 
 + 
 +=== rtod() === 
 +<code c> 
 +rtod(fname, start_adr, end_adr) 
 +char *fname; 
 +unsigned start_adr, end_adr; 
 +</​code>​ 
 +Сохранение блока данных из RAM в файле ''​fname''​. 
 + 
 +{{anchor:​disk-io-vram}} 
 +==== Дисковый ввод/​вывод для VRAM MSX2 ==== 
 + 
 +Специальный набор дисковых функций:​ дисковый ввод/​вывод для VRAM [[msx:​msx_2|MSX2]]. 
 +=== dtova2() === 
 +<code c> 
 +char dtova2(fname,​ dx, dy) 
 +char *fname; 
 +unsigned dx, dy; 
 +</​code>​ 
 +Загрузка файла в активную страницу VRAM с диска. Эта функция «понимает» компрессированный формат данных (ширина < 0, то есть ''​-width''​). Вы можете дополнительно специфицировать тип данных,​ которые вы загружаете установкой системной переменной ''​[[#​_picture]]''​ в состояние TRUE (по умолчанию) или FALSE. Для этой функции ''​dir = R_D'',​ ''​lop = PSET''​ в любом случае её использования. 
 + 
 +Если вы установили ''​_picture = FALSE'',​ данные не анализируются на наличие заголовка ''​width''/''​heght''​ и загружаются в VRAM последовательно до обнаружения ситуации EOF. ''​dtova2()''​ возвращает ОК (0) или номер ошибки для ''​[[#​errmsg()]]'',​ если ошибка имела место при чтении информации с диска. 
 + 
 +[[msx:​bios#​subrom|SubROM]] не используется,​ поэтому эта функция работает корректно. 
 + 
 +Внимание! Иногда вы можете получать неожиданные результаты,​ если адреса загрузки VRAM пересекают границу 0xFFFF…0x10000. Это связано с некоторыми особенностями [[msx:​yamaha_v9938:​yamaha_v9938|V9938]] — рекомендуем в этих случаях использовать раздельную загрузку нижних и верхних 64 кбайт VRAM. 
 + 
 +=== rtova2() === 
 +<code c> 
 +rtova2(radr,​ dx, dy) 
 +unsigned radr, dx, dy; 
 +</​code>​ 
 +Пересылка данных из RAM в активную страницу VRAM с координатами ''​dx'',''​dy''​. Эта функция также «понимает» компрессированный формат данных (ширина < 0, то есть ''​-width''​). Вы так же можете дополнительно специфицировать тип данных,​ которые вы пересылаете установкой системной переменной ''​[[#​_picture]]''​ в состояние TRUE (по умолчанию) или FALSE. Для этой функции ''​dir=R_D'',​ ''​lop=PSET''​ в любом случае её использования. [[msx:​bios#​subrom|SubROM]] не используется. 
 + 
 +=== vtoda2() === 
 +<code c> 
 +char vtoda2(fname,​ sx, sy, width, height) 
 +char *fname; 
 +unsigned sx, sy, width, height; 
 +</​code>​ 
 +Сохранение данных из активной страницы VRAM (координаты ''​sx'',''​sy'',​ размеры width и height) в файле ''​fname''​. Функция является обратной по отношению к ''​[[#​dtova2()]]''​. Компрессор данных не имплементирован из-за сравнительно большого объёма занимаемой им оперативной памяти. ''​vtoda2()''​ возвращает ОК (0) или номер ошибки для ''​[[#​errmsg()]]'',​ если ошибка имела место при записи информации на диск. 
 + 
 +[[msx:​bios#​subrom|SubROM]] не используется. 
 + 
 +FIXME 
 +__//​Примечание.//​__ Для компрессии файлов в подобных форматах автором разработана программа [[#​PICO.COM|Picture Compressor]],​ которая не входит в состав ПС «МАЭСТРО» и может быть в дальнейшем поставлена по специальному заказу. Эта утилита разработана специально для визуальной компрессии/​экспандирования графических данных в формате COPY (Data) Screen 5. 
 + 
 +=== vtodpage() === 
 +<code c> 
 +vtodpage(fname,​ page_no, len) 
 +char *fname, page_no; 
 +unsigned len; 
 +</​code>​ 
 +Прямой dump страницы page_no VRAM в файл fname объемом len байт. 
 + 
 +Dump всегда начинается с начала страницы (0…3 для Screen 5 или 6 и 0…1 для Screen 7 или 8) с координатами (0; 0) и включает данные в VRAM длиной ''​len''​ байт. 
 + 
 +''​vtodpage()''​ возвращает ОК (0) или номер ошибки для ''​[[#​errmsg()]]'',​ если ошибка имела место при записи информации на диск. 
 + 
 +[[msx:​bios#​subrom|SubROM]] не используется. 
 + 
 +=== xtova2() === 
 +<code c> 
 +char xtova2(fname,​ dx, dy) 
 +char *fname; 
 +unsigned dx, dy; 
 +</​code>​ 
 +Эта функция сначала проверяет Extra Data для конца области External (переключатель '​-f',​ см. ''​[[#​geteda()]]''​ и [[#​EDL.COM|Extra Data Linker]]) и, в случае,​ если данные с именем ''​fname''​ (''​upshifted''​ & ''​deblanked''​) найдены,​ пересылает их в ''​dx'',''​dy''​ VRAM. В противном случае ''​xtova2()''​ пытается загрузить файл с именем ''​fname''​ с диска. Эта функция «понимает» компрессированый формат данных. 
 + 
 +''​xtova2()''​ возвращает ОК (0) или номер ошибки для ''​[[#​errmsg()]]'',​ если ошибка имела место при чтении информации с диска. 
 + 
 +[[msx:​bios#​subrom|SubROM]] не используется. 
 + 
 +==== COPY с абсолютной адресацией dy/sy (0…1024 или 0…512) ==== 
 + 
 +=== vtov() === 
 +<code c> 
 +vtov(sx, sy, dx, dy, width, height, dir, lop) 
 +unsigned sx, sy, dx, dy, width, height; 
 +char dir, lop; 
 +</​code>​ 
 +Пересылка из ''​sx'',''​sy''​ VRAM в ''​dx'',''​dy''​ VRAM прямоугольного блока размером ''​width'',''​height''​. Направление пересылки — ''​dir'',​ логическая операция — ''​lop''​ (см. ''​[[#​dtov()]]''​). Используется [[msx:​bios#​subrom|SubROM]]. 
 + 
 +=== vtovb() === 
 +<code c> 
 +vtovb(sx, sy, dx, dy, width, height, dir) 
 +unsigned sx, sy, dx, dy, width, height; 
 +char dir; 
 +</​code>​ 
 +Высокоскоростная пересылка без логических операций из ''​sx'',''​sy''​ VRAM в ''​dx'',''​dy''​ VRAM прямоугольного блока размером ''​width'',''​height''​. Направление пересылки — ''​dir''​ (см. ''​[[#​dtov()]]''​). Горизонтальный размер и начало блока автоматически выравниваются на границу БАЙТА (не точки!). 
 + 
 +[[msx:​bios#​subrom|SubROM]] не используется. 
 + 
 +=== rtov() === 
 +<code c> 
 +rtov(sadr, dx, dy, dir, lop) 
 +unsigned sadr, dx, dy; 
 +char dir, lop; 
 +</​code>​ 
 +Пересылка блока, имеющего заголовок ширины и высоты из RAM в ''​dx'',''​dy''​ VRAM. Направление пересылки — ''​dir'',​ логическая операция — ''​lop''​ (см. ''​[[#​dtov()]]''​). 
 + 
 +Используется [[msx:​bios#​subrom|SubROM]]. 
 + 
 +=== vtor() === 
 +<code c> 
 +vtor(sx, sy, width, height, radr, dir) 
 +unsigned sx, sy, dx, dy, width, heigth, radr; 
 +char dir; 
 +</​code>​ 
 +Пересылка блока из ''​sx'',''​sy''​ VRAM в RAM по адресу ''​radr''​ размерами ''​width'',''​height''​. Направление пересылки — ''​dir''​. 
 + 
 +Используется [[msx:​bios#​subrom|SubROM]]. 
 + 
 +==== COPY с адресацией dy/sy внутри активной страницы (0…256) ==== 
 + 
 +=== vtova() === 
 + 
 +<code c> 
 +vtova(sx, sy, dx, dy, width, height, dir, lop) 
 +unsigned sx, sy, dx, dy, width, height; 
 +char dir,lop; 
 +</​code>​ 
 +Пересылка из ''​sx'',''​sy''​ VRAM в ''​dx'',''​dy''​ VRAM прямоугольного блока размером ''​width'',''​height''​. 
 + 
 +Направление пересылки — ''​dir'',​ логическая операция — ''​lop''​ (см. ''​[[#​dtov()]]''​). 
 + 
 +Используется [[msx:​bios#​subrom|SubROM]]. 
 + 
 +=== rtova() === 
 +<code c> 
 +rtova(sadr, dx, dy, dir, lop) 
 +unsigned sadr, dx, dy; 
 +char dir, lop; 
 +</​code>​ 
 +Пересылка блока, имеющего заголовок ширины и высоты из RAM в ''​dx'',''​dy''​ VRAM. 
 + 
 +Направление пересылки — ''​dir'',​ логическая операция — ''​lop''​ (см. ''​[[#​dtov()]]''​). 
 + 
 +Используется [[msx:​bios#​subrom|SubROM]]. 
 + 
 +==== COPY с прямой адресацией RAM и VRAM ==== 
 + 
 +=== rtovlow() === 
 +<code c> 
 +rtovlow(radr,​ vadr, len) 
 +unsigned radr, vadr, len; 
 +</​code>​ 
 +Пересылка ''​len''​ байт из RAM в нижние 64 кбайт VRAM. 
 + 
 +[[msx:​bios#​subrom|SubROM]] не используется. 
 + 
 +=== rtovhi() === 
 +<code c> 
 +rtovhi(radr,​ vadr, len) 
 +unsigned radr, vadr, len; 
 +</​code>​ 
 +Пересылка ''​len''​ байт из RAM в верхние 64 кбайт VRAM. 
 + 
 +[[msx:​bios#​subrom|SubROM]] не используется. 
 + 
 +=== vtorlow() === 
 +<code c> 
 +vtorlow(vadr,​ radr, len) 
 +unsigned vadr, radr, len; 
 +</​code>​ 
 +Пересылка ''​len''​ байт из нижних 64 кбайт VRAM в RAM. 
 + 
 +[[msx:​bios#​subrom|SubROM]] не используется. 
 + 
 +=== vtorhi() === 
 +<code c> 
 +vtorhi(vadr,​ radr, len) 
 +unsigned vadr, radr, len; 
 +</​code>​ 
 +Пересылка ''​len''​ байт из верхних 64 кбайт VRAM в RAM. 
 + 
 +[[msx:​bios#​subrom|SubROM]] не используется. 
 + 
 +===== GRPLIB3 ===== 
 + 
 +Раздел Библиотеки GRPLIB3 
 + 
 +{{anchor:​drawing_functions}} 
 +==== Функции для рисования точек, линий, блоков и пр. ==== 
 +Функции рисования для MSX2 (Screen 5…8) 
 +=== pset() === 
 +<code c> 
 +pset(x, y, cl) 
 +int x, y; 
 +char cl; 
 +</​code>​ 
 +Рисовать точку с координатами ''​x'',''​y''​ на активной странице цветом ''​cl''​. 
 + 
 +=== point() === 
 +<code c> 
 +char point(x, y) 
 +int x, y; 
 +</​code>​ 
 +Получить цвет точки с координатами ''​x'',''​y''​ на активной странице. 
 + 
 +=== line() === 
 +<code c> 
 +line(x1, y1, x2, y2, cl, lop) 
 +int x1, y1, x2, y2; 
 +char cl, lop; 
 +</​code>​ 
 +Рисовать линию с координатами ''​x1'',''​y1''​ — ''​x2'',''​y2''​ на активной странице цветом ''​cl''​ с логической операцией ''​lop''​. 
 + 
 +=== box() === 
 +<code c> 
 +box(x1, y1, x2, y2, cl, lop) 
 +int x1, y1, x2, y2; 
 +char cl,lop; 
 +</​code>​ 
 +Рисовать прямоугольник с координатами ''​x1'',''​y1''​ — ''​x2'',''​y2''​ на активной странице цветом ''​cl''​ с логической операцией ''​lop''​. 
 + 
 +=== boxf() === 
 +<code c> 
 +boxf(x1, y1, x2, y2, cl, lop) 
 +int x1,y1, x2, y2; 
 +char cl,lop; 
 +</​code>​ 
 +Рисовать закрашенный прямоугольник с координатами ''​x1'',''​y1''​ — ''​x2'',''​y2''​ на активной странице цветом ''​cl''​ с логической операцией ''​lop''​. 
 + 
 +{{anchor:​output_characters_on_graphic_screen}} 
 +==== Вывод символов на графический экран ==== 
 + 
 +Вывод символов на графический экран MSX2 (Screen 5…8) 
 + 
 +=== pstep() === 
 +<code c> 
 +pstep(px, py) 
 +int px, py; 
 +</​code>​ 
 +Задать горизонтальный/​вертикальный шаг (расстояние в точках) для вывода символов на графический экран (по умолчанию 8 по обеим осям). 
 + 
 +=== gputch() === 
 +<code c> 
 +gputch(x, y,fcl, bcl, c) 
 +int x, y, fcl, bcl; 
 +char c; 
 +</​code>​ 
 +Вывести символ ''​c''​ цветом ''​fcl''​ на графический экран с координатами ''​x'',''​y'',​ предварительно нарисовав под ним закрашенный прямоугольник цветом ''​bcl''​. 
 + 
 +Прямоугольник может быть невидимым,​ если для него используется цвет (палитра) 0 — это применимо также для всех остальных функций вывода строк на графический экран. 
 + 
 +Функция ''​gputch()''​ не распознает символ перевода строки ''​\n''​ 
 + 
 +=== gputs() === 
 +<code c> 
 +gputs(x, y, fcl, bcl, str) 
 +int x, y, fcl, bcl; 
 +char *str; 
 +</​code>​ 
 +Вывести строку ''​str''​ цветом ''​fcl''​ на графический экран с координатами ''​x'',''​y''​ предварительно рисуя под каждым символом закрашенный прямоугольник цветом ''​bcl''​. 
 + 
 +Прямоугольник может быть невидимым,​если для него используется цвет (палитра) 0. 
 + 
 +Функция ''​gputs()''​ не распознает символ перевода строки ''​\n''​ 
 + 
 +=== gputs6() === 
 +<code c> 
 +gputs6(x, y,fcl, bcl, str) 
 +int x, y, fcl, bcl; 
 +char *str; 
 +</​code>​ 
 +Вывести строку ''​str''​ цветом ''​fcl''​ на графический экран с координатами ''​x'',''​y''​ предварительно рисуя под каждым символом закрашенный прямоугольник цветом ''​bcl''​. 
 + 
 +Прямоугольник может быть невидимым,​ если для него используется цвет (палитра) 0. Все символы выводятся с шагом 6 точек по горизонтали независимо от того, какие значения были заданы при помощи ''​[[#​pstep()]]''​ и не изменяя этих значений. Это удобно при многозадачном использовании,​ так как ресурсы ''​px'',''​py''​ ''​[[#​pstep()]]''​ являются общими для всех задач. 
 + 
 +Функция ''​gputs6()''​ не распознает символ перевода строки ''​\n''​ 
 + 
 +=== gprintf() === 
 +<code c> 
 +gprintf(x, y, fcl, bcl, format, arg1, ..., argN) 
 +int x, y, fcl, bcl; 
 +char *format; 
 +</​code>​ 
 +Форматированный вывод на графический экран (см. ''​printf()''​ [[bds_c:​bds_c|]] для детального описания всех форматов вывода данных). 
 + 
 +По символу перевода строки ''​\n''​ выполняется стандартная операция CR LF при которой ''​x''​ устанавливается в 0, а ''​y+=py''​ (см. ''​[[#​pstep()]]''​). 
 + 
 +=== gdump() === 
 +<code c> 
 +gdump(x, y, fcl, bcl, start_adr, end_adr) 
 +int x, y, fcl, bcl; 
 +unsigned start_adr,​end_adr;​ 
 +</​code>​ 
 +Шестнадцатеричный dump памяти на графический экран, начиная со ''​start_adr''​ и кончая ''​end_adr''​. 
 + 
 +=== *sprintf() === 
 +<code c> 
 +char *sprintf(buf,​ format, arg1, ..., argN) 
 +char *buf, *format; 
 +</​code>​ 
 +То же самое, что и обычный ''​sprintf()''​ [[bds_c:​bds_c|]],​ но возвращает указатель на ''​buf''​ для вложенного использования в других функциях. 
 +\\ !!!ПЕРЕОПРЕДЕЛЕНИЕ!!! 
 + 
 +=== *fmt === 
 +<code c> 
 +char *fmt(format,​arg1,​...,​argN) 
 +char *format; 
 +</​code>​ 
 +Функция аналогичная ''​[[#​*sprintf()]]'',​ но использующая системный буфер ''​_pbuf[32]''​ для форматирования строк. Удобна для компактной записи таких операторов как <code c>​putstrt(y,​x,​fmt("​%d",​n));</​code>​ 
 +  
 +Если вы ограничены по объёму памяти External и не планируете использовать эту функцию,​ то можете написать 
 +<code c>#​define NO_PBUF</​code>​ 
 +перед 
 +<code c>#​include grpmsx1.h</​code>​ 
 +или 
 +<code c>#​include grplib0.h</​code>​ 
 + 
 +=== *trt === 
 +<code c> 
 +char *trt(str) 
 +char *str; 
 +</​code>​ 
 + 
 +Перекодировка строки с использованием таблицы _trtab1 длиной 256 байт. (эта же таблица используется в функции ''​[[#​putstrt()]]''​) 
 + 
 +Функция возвращает указатель на переданную ей строку str. 
 + 
 +Пример использования:​ 
 +<code c> 
 +trt(fmt("<​format string>",​vars));​ 
 +</​code>​ 
 + 
 +{{anchor:​test_screen_functions}} 
 +==== Прямой доступ к текстовому экрану ==== 
 + 
 +Текстовые функции для Screen 0 (X: 1…80, Y: 1…24) 
 + 
 +=== posx() === 
 +<code c> 
 +char posx() 
 +</​code>​ 
 +Возвратить текущую X-координату текстового курсора. 
 + 
 +=== posy() === 
 +<code c> 
 +char posy() 
 +</​code>​ 
 +Возвратить текущую Y-координату текстового курсора. 
 + 
 +=== locate() === 
 +<code c> 
 +locate(tx, ty) 
 +char tx, ty; 
 +</​code>​ 
 +Поместить текстовой курсор в позицию ''​tx''​ (1…80), ''​ty''​ (1…24). 
 + 
 +=== putsxy() === 
 +<code c> 
 +putsxy(tx, ty, str) 
 +char tx, ty, *str; 
 +</​code>​ 
 +Вывести строку ''​str''​ непосредственно в VRAM с координатами ''​tx''​ (1…80), ''​ty''​ (1…24). 
 + 
 +Внимание! Позиция текстового курсора не изменяется! 
 + 
 +=== getchrv() === 
 +<code c> 
 +char getchrv(tx, ty) 
 +char tx, ty; 
 +</​code>​ 
 +Возвратить код символа,​ находящегося на экране в позиции ''​tx''​ (1…80), ''​ty''​ (1…24). 
 + 
 +Внимание! Позиция текстового курсора не изменяется! 
 + 
 +=== putchrv() === 
 +<code c> 
 +putchrv(tx, ty, c) 
 +char tx, ty, c; 
 +</​code>​ 
 +Поместить символ непосредственно в VRAM в позицию экрана ''​tx''​ (1…80), ''​ty''​ (1…24). 
 + 
 +Внимание! Позиция текстового курсора не изменяется! 
 + 
 +=== inline() === 
 +<code c> 
 +char inline(tx, ty, len, buf) 
 +char tx, ty, len, *buf; 
 +</​code>​ 
 +Вводить не более ''​len''​ символов с клавиатуры компьютера с отображением их на экране начиная с позиции ''​tx''​ (1…80), ''​ty''​ (1…24) и записью в ''​buf''​. Завершающие ввод пробелы (если присутствуют) усекаются в ''​buf'',​ размер которого должен быть как минимум len+1 для записи завершающего строку двоичного нуля. Нажатие <​key>'​Ввод '​⏎</​key>​ (CR — признак конца ввода.) 
 + 
 +Возвращает длину строки в ''​buf''​. Нажатие клавиш <​key>​ESC</​key>​ или <​key>​STOP</​key>​ приводит к прекращению ожидания ввода с клавиатуры с возвратом длины 0. 
 + 
 +Внимание! Позиция текстового курсора не изменяется! 
 + 
 +=== clrtxt() === 
 +<code c> 
 +clrtxt() 
 +</​code>​ 
 +Очистить текстовой экран. 
 + 
 +=== dline() === 
 +<code c> 
 +dline(lnum) 
 +char lnum; 
 +</​code>​ 
 +Удалить на экране строку ''​lnum''​ (1…24). 
 + 
 +=== iline() === 
 +<code c> 
 +iline(lnum) 
 +char lnum;  
 +</​code>​ 
 +Вставить на экране строку ''​lnum''​ (1…24). 
 + 
 +{{anchor:​text_menus_in_graphical_mode}} ​  
 +==== Текстовые меню в графическом режиме ==== 
 +Функции для работы с оконными меню в Screen 5…8 
 + 
 +=== paletwin() === 
 +<code c> 
 +paletwin(fg,​ bg) 
 +char fg, bg; 
 +</​code>​ 
 +Установить цвета (палитры) переднего и заднего плана для оконных меню. По умолчанию 7, 8. 
 + 
 +=== swpaletw() === 
 +<code c>char swpaletw()</​code>​ 
 +Обменять (swap) текущие палитры переднего и заднего плана для оконных меню. Вернуть палитру переднего плана. 
 + 
 +=== windsel() === 
 +<code c>char windsel(x, y, head, alt1, ..., alt23) 
 +unsigned x, y; 
 +char *head, *alt1, ..., *alt23; 
 +</​code>​ 
 +Открыть оконное меню на активной странице VRAM (временно назначив активную страницу на страницу,​ показываемую на экране) и возвратить номер выбранной оператором альтернативы ''​alt1,​ ..., alt23''​. Возвратить RESUME (1) без ожидания выбора альтернативы в случае,​ если присутствует только один заголовок меню (header) или заголовок и только одна альтернатива (alt1). 
 + 
 +Меню управляется мышью из порта 1 или 2 или клавишами курсора,​ если мышь не подключена к компьютеру (распознаётся автоматически). 
 + 
 +В случае использования клавиш курсора,​ клавиша <​key>​ПРОБЕЛ</​key>​ выполняет функцию левой кнопки мыши (DO), а <​key>​ESC</​key>​ — правой (UNDO). Если нажата клавиша UNDO, ''​windsel()''​ возвращает значение UNDO (255). 
 + 
 +Во время ожидания ответа оператора эта функция вызывает ''​[[#​totick()]]''​ для нормального выполнения параллельных процессов и может быть абортирована при помощи ''​[[#​ABANDONWINDOW]]''​ — в этом случае ''​windsel()''​ возвращает значение ABORT (0). 
 + 
 +Внимание! Для нормального выполнения параллельных процессов рекомендуется вызывать ''​windsel()''​ из главной программы или из ''​[[#​process0()]]''​. 
 + 
 +=== rewindow() === 
 +<code c> 
 +rewindow(mother_page) 
 +char mother_page;​ 
 +</​code>​ 
 +Восстановить область на активной странице,​ затёртую группой последовательно выведенных оконных меню, используя материнскую страницу ''​mother_page''​ (0…3) с эталоном изображения. Это возможно,​ так как все последовательно выводимые оконные меню накапливают граничные координаты используемых ими областей экрана до тех пор, пока ''​rewindow()''​ не сбросит их в ноль. 
 + 
 +{{anchor:​polling_special_keyboard_keys}} 
 +==== Опрос специальных клавиш клавиатуры ==== 
 + 
 +|''​char isesc()''​|Возвращает TRUE, если нажата клавиша <​key>​ESC</​key>​| 
 +|''​char istab()''​|Возвращает TRUE, если нажата клавиша <​key>​TAB</​key>​| 
 +|''​char isctrl()''​|Возвращает TRUE, если нажата клавиша <​key>​CTRL</​key>​| 
 +|''​char isshift()''​|Возвращает TRUE, если нажатa клавиша <​key>​SHIFT</​key>​| 
 +|''​char iscaps()''​|Возвращает TRUE, если нажата клавиша <​key>​CAPS</​key>​| 
 +|''​char isgraph()''​|Возвращает TRUE, если нажата клавиша <​key>​GRAPH</​key>​| 
 +|''​char isspbar()''​|Возвращает TRUE, если нажатa клавиша <​key>​SPACE (пробел)</​key>​| 
 +|''​char iscode()''​|Возвращает TRUE, если нажата клавиша <​key>​CODE (РУС)</​key>​| 
 +|''​char isselect()''​|Возвращает TRUE, если нажата клавиша <​key>​SELECT</​key>​| 
 +|''​char isstop()''​|Возвращает TRUE, если нажата клавиша <​key>​STOP</​key>​| 
 +|''​char ishome()''​|Возвращает TRUE, если нажата клавиша <​key>​HOME (CLS)</​key>​| 
 +|''​char isins()''​|Возвращает TRUE, если нажата клавиша <​key>​INS</​key>​| 
 +|''​char isdel()''​|Возвращает TRUE, если нажата клавиша <​key>​DEL</​key>​| 
 +|''​char isf1()''​|Возвращает TRUE, если нажата клавиша <​key>​F1 (F6)</​key>​| 
 +|''​char isf2()''​|Возвращает TRUE, если нажата клавиша <​key>​F2 (F7)</​key>​| 
 +|''​char isf3()''​|Возвращает TRUE, если нажата клавиша <​key>​F3 (F8)</​key>​| 
 +|''​char isf4()''​|Возвращает TRUE, если нажата клавиша <​key>​F4 (F9)</​key>​| 
 +|''​char isf5()''​|Возвращает TRUE, если нажата клавиша <​key>​F5 (F10)</​key>​| 
 +|''​char isfunkey()''​|Возвращает TRUE, если нажата любая из клавиш <​key>​F1</​key>​...<​key>​F5</​key>​| 
 +|''​char isleft()''​|Возвращает TRUE, если нажата клавиша курсора "​влево"​| 
 +|''​char isright()''​|Возвращает TRUE, если нажата клавиша курсора "​вправо"​| 
 +|''​char isup()''​|Возвращает TRUE, если нажата клавиша курсора "​вверх"​| 
 +|''​char isdown()''​|Возвращает TRUE, если нажата клавиша курсора "​вниз"​| 
 +|''​char iscursor()''​|Возвращает TRUE, если нажата любая клавиша курсора| 
 +|''​char ismouse1()''​|Возвращает TRUE, если мышь подключена к порту 1| 
 +|''​char ismouse2()''​|Возвращает TRUE, если мышь подключена к порту 2| 
 +|''​char ismouse(mp)''​|Возвращает TRUE, если мышь подключена к порту ''​mp''​| 
 +|''​char istrig(tn)''​|Возвращает TRUE, если нажат триггер ''​tn''​| 
 +|''​char isdclick(tn)''​|Возвращает TRUE, если триггер ''​tn''​ нажат дважды| 
 +|''​fretrig(tn)''​|Ждать отпускания триггера ''​tn''​| 
 +|''​char iscr()''​|Возвращает TRUE, если нажата клавиша <​key>'​Ввод '​⏎</​key>​ (CR — возврат каретки)| 
 +|''​char isbs()''​|Возвращает TRUE, если нажатa клавиша <​key>​BS</​key>​| 
 + 
 +===== GRPLIB4 ===== 
 +Раздел Библиотеки GRPLIB4 
 + 
 +{{anchor:​sprintes}} 
 +==== Спрайты ==== 
 + 
 +=== lsphex() === 
 +<code c> 
 +lsphex(patnum,​ hexstr) 
 +char patnum, *hexstr; 
 +</​code>​ 
 +Записать в VRAM Sprite Generator Table начиная со спрайта ''​patnum''​ конфигурацию спрайта (спрайтов),​ заданную литеральной строкой с шестнадцатеричными цифрами (аналогично ''​[[#​inith()]]''​). Несколько подряд идущих спрайтов могут быть инициализированы за одно выполнение ''​lsphex()''​ 
 + 
 +=== lsphex8() === 
 +<code c> 
 +lsphex8(patnum,​ hexstr1, ..., hexstr8) 
 +char patnum, *hexstr1, ..., *hexstr8; 
 +</​code>​ 
 +То же самое, что ''​[[#​lsphex()]]'',​ но, для удобства,​ слишком длинная литеральная строка может быть разбита на максимум 8 более коротких строк. Если общее количество таких строк меньше 8 — последняя строка должна быть пустой:​ %%""​%% 
 + 
 +=== lspmem() === 
 +<code c> 
 +lspmem(patnum,​ sadr, eadr) 
 +char patnum; 
 +unsigned sadr, eadr; 
 +</​code>​ 
 +Записать в VRAM Sprite Generator Table начиная со спрайта ''​patnum''​ конфигурацию спрайта (спрайтов),​ заданную в RAM начиная с адреса ''​sadr''​ и кончая адресом ''​eadr''​. 
 + 
 +Ограничения на длину записываемых данных отсутствуют. 
 + 
 +=== getpat() === 
 +<code c> 
 +char getpat(patnum,​ buf) 
 +char patnum, *buf; 
 +</​code>​ 
 +Переписать конфигурацию спрайта ''​patnum''​ из VRAM Sprite Generator Table в ''​buf''​ (8 или 32 байта в зависимости от размеров спрайтов). 
 + 
 +=== lschex() === 
 +<code c> 
 +lschex(planenum,​ hexstr) 
 +char planenum, *hexstr; 
 +</​code>​ 
 +//​Только для SCREEN 4…8 MSX2// 
 + 
 +Загрузить цвет спрайта (построчную окраску,​ 16 байт), ассоциированный с планом спрайта = ''​planenum''​ из литеральной строки с шестнадцатеричными цифрами (аналогично ''​[[#​inith()]]''​). Несколько подряд идущих планов спрайтов могут быть инициализированы за одно выполнение ''​lschex()''​. Каждый из 16 байт имеет следующую структуру:​ 
 +<code c> 
 +{ EC  CC  IC  0  <colour code 0…15> } 
 +</​code>​ 
 + 
 +=== lschex8() === 
 +<code c> 
 +lschex8(planenum,​ hexstr1, ..., hexstr8) 
 +char planenum, *hexstr1, ..., *hexstr8; 
 +</​code>​ 
 +//​Только для SCREEN 4…8 MSX2// 
 + 
 +Используется аналогично ''​[[#​lsphex8()]]''​ 
 + 
 +=== lscmem() === 
 +<code c> 
 +lscmem(planenum,​ sadr, eadr) 
 +char planenum; 
 +unsigned sadr, eadr; 
 +</​code>​ 
 +//​Только для SCREEN 4…8 MSX2// 
 + 
 +Загрузить цвета планов спрайтов начиная с ''​planenum''​ из RAM с адресов ''​sadr''​ по ''​eadr''​ 
 + 
 +Ограничения на длину записываемых данных отсутствуют. 
 + 
 +=== getcol() === 
 +<code c> 
 +char getcol(planenum,​ buf) 
 +char planenum, *buf; 
 +</​code>​ 
 +//​Только для SCREEN 4…8 MSX2// 
 +Переписать цвет плана спрайта ''​planenum''​ в ''​buf''​ (16 байт) и вернуть количество значащих байт (8 или 16) в зависимости от размера спрайтов. 
 + 
 +=== sprite() === 
 +<code c> 
 +sprite(planenum,​ patnum1, x1, y1, patnum2, x2, y2, ..., patnumN, xN, yN) 
 +char planenum, patnum1, x1, y1, patnum2, x2, y2, ..., patnumN, xN, yN; 
 +</​code>​ 
 +Ассоциировать группу последовательно идущих планов спрайтов начиная с ''​planenum''​ со спрайт-паттернами ''​patnum1…patnumN''​ и вывести их на экран соответственно в позициях ''​(x1;​ y1)…(xN; yN)''​ одновременно. Если очередной ''​patnum''​ (исключая первый) равен нулю — считается что список параметров функции исчерпан (это функция с переменным числом параметров). При выводе спрайтов на экран автоматически производится коррекция координаты Y каждого плана спрайта на -1 (компенсация неудачного решения в VDP). Функция sprite() применима как к MSX1, так и к MSX2. 
 + 
 +Координаты спрайтов всегда находятся в диапазоне 0…255 (в том числе и для Screen 6, 7 — см. [[msx:​yamaha_v9938:​yamaha_v9938|V9938]]). 
 + 
 +{{anchor:​disks}} 
 +==== Доступ к оглавлению диска ==== 
 + 
 +=== diskdir() === 
 +<code c> 
 +char diskdir(dirmask,​ buf1700) 
 +char *dirmask, *buf1700; 
 +</​code>​ 
 +Поместить оглавление диска в buf1700 (длиной 1700 байт). 
 + 
 +Каждая точка входа, полученная при помощи ''​diskdir()'',​ имеет длину 15 байт и следующую структуру:​ 
 +<​code>​ 
 +d:​ffffffff.sss\0 
 +</​code>​ 
 +''​diskdir()''​ возвращает количество точек входа, помещённых в ''​buf1700'',​ и релевантных ''​dirmask''​ 
 + 
 +''​dirmask''​ является символической строкой (оканчивающейся двоичным нулём) в стандартной нотации [[msx:​dos:​|]]:​ 
 +<​code>​ 
 +[drive:​]filename[.suffix]\0 
 +</​code>​ 
 +которая может включать в себя символы ''​*''​ и ''?'',​ а также дополнительный символ ''​!''​ ([AND] NOT). 
 +Примеры:​ 
 +<​code>​ 
 +*.com!ab*.com!cde.com 
 +</​code>​ 
 +означает все COM-файлы кроме начинающихся с ''​ab''​ и ''​cde''​. 
 +<​code>​ 
 +!*.c 
 +</​code>​ 
 +означает все файлы, кроме имеющих суффикс ''​.c''​ 
 + 
 +Пустая строка:​ <​code>​dirmask (""​)</​code>​ эквивалентна ''​*.*''​ 
 + 
 +=== sortdir() === 
 +<code c> 
 +sortdir(buf1700,​n_entry) 
 +char *buf1700,​n_entry;​ 
 +</​code>​ 
 +Сортировать ''​n_entry''​ точек входа в оглавление buf1700, полученных после выполнения diskdir(). Сортировка производится в полуинверсной форме:​ 
 +<​code>​ 
 +d:​sss.ffffffff 
 +</​code>​ 
 + 
 +Результат сортировки записывается в тот же буфер в нормальной форме:​ 
 +<​code>​ 
 +d:​ffffffff.sss 
 +</​code>​ 
 + 
 +Вы можете использовать функцию ''​qsort()''​ [[bds_c:​bds_c|]] для сортировки точек входа обычным образом. 
 + 
 +{{anchor:​psg}} 
 +==== Работа со звуковым генератором (PSG) ==== 
 + 
 +Работа со [[msx:​psg:​psg|звуковым генератором]] (PSG). 
 + 
 +=== wpsg() === 
 +<code c> 
 +wpsg(reg, byte) 
 +char reg, byte; 
 +</​code>​ 
 +Записать ''​byte''​ в регистр ''​reg''​ [[msx:​psg:​psg|PSG]] 
 + 
 +=== rpsg() === 
 +<code c> 
 +char rpsg(reg) 
 +char reg; 
 +</​code>​ 
 +Читать байт из регистра ''​reg''​ [[msx:​psg:​psg|PSG]] 
 + 
 +=== sndreset() === 
 +<code c> 
 +sndreset() 
 +</​code>​ 
 +Сброс [[msx:​psg:​psg|PSG]] в начальное состояние. 
 + 
 +=== sound() === 
 +<code c> 
 +sound(r0, ..., r13, ctrl, waveform, modstep, modwidth, chanconfig, duration) 
 +int r0, ..., r13, ctrl; 
 +char waveform, modstep, modwidth, chanconfig;​ 
 +unsigned duration; 
 +</​code>​ 
 +Генерировать звук при помощи [[msx:​psg:​psg|PSG]] и программного Extra LFO для частотной модуляции звука. Значения ''​r0…r13''​ загружаются в соответствующие регистры PSG (отрицательные значения игнорируются). Если ''​ctrl''​ не равен нулю, то используется Extra LFO для каналов PSG, определяемых байтом ''​chancofig'':​ 
 + 
 +<​code>​ 
 +0000 ABCN 
 +     ​││││ 
 +     ​│││└── 1: модулировать шум 
 +     ​││└─── 1: модулировать канал C 
 +     ​│└──── 1: модулировать канал B 
 +     ​└───── 1: модулировать канал А 
 +</​code>​ 
 +При этом: 
 +|''​waveform''​|0 или 1|форма волны| 
 +|''​modstep''​|0…255|шаг девиации частоты| 
 +|''​modwidth''​|0…255|ширина девиации частоты| 
 +|''​duration''​|1…0xFFFF|длительность в «тиках» таймера| 
 +Функцией ''​sound()''​ автоматически вызывается ''​[[#​totick()]]''​ для обеспечения возможности параллельного выполнения других процессов во время генерации звуков,​ имеющих большу́ю длительность (duration). 
 + 
 +FIXME 
 +Примечание. Для упрощения разработки и создания новых звуковых эффектов автором разработана утилита PSG Extra Editor, которая позволяет создавать звуки в режиме полноэкранного редактирования всех параметров функции sound() и сохранять/​загружать банки звуков в виде ASCII-файлов,​ содержащих готовые к вставке в программу операторы ''​sound()''​. Эта утилита не входит в состав ПС «МАЭСТРО» и может поставляться в дальнейшем по отдельному заказу. 
 + 
 +=== sound1() === 
 +<code c> 
 +sound1(str) 
 +char *str; 
 +</​code>​ 
 +Альтернативная версия функции ''​[[#​sound()]]''​ для управления только каналом #1 (А) [[msx:​psg:​psg|PSG]]. Эту функцию удобно использовать для создания отдельных звуковых эффектов в канале #1 во время исполнения какой–либо музыки,​ разработанной с использованием ПС «МЕДИА» для системной музыкальной очереди MSX. Кроме этого, ''​sound1()''​ является более компактным вариантом функции ''​[[#​sound()]]''​ (как по объёму генерируемого кода, так и по данным). 
 + 
 +Строка ''​str''​ представляет собой последовательность байтов следующего вида: 
 +^байт:​|r0|r1|r6|r7|r8|r11|r12|r13|ctrl|wf|ms|mw|ch|dur| 
 +^смещение:​|+0|+1|+2|+3|+4|+5|+6|+7|+8|+9|+10|+11|+12|+13–14| 
 +где: 
 +|''​r0…r13''​|регистры PSG| 
 +|''​ctrl'',​ ''​wf'',​ ''​ms'',​ ''​mw'',​ ''​ch'',​ ''​dur''​|соответственно ''​ctrl'',​ ''​waveform''​| 
 +|''​modstep'',​ ''​modwidth'',​ ''​chanconfig''​ и ''​duration''​ (2 байта)|аналогично функции ''​[[#​sound()]]''​| 
 + 
 +Примечание 1. Формат записи строки для sound1() также поддерживается утилитой PSG Extra Editor (см. примечание выше). 
 + 
 +FIXME 
 +Примечание 2. ПС «МЕДИА» не является компонентой ПС «МАЭСТРО» и разработано другим автором для использования совместно с ПС «МАЭСТРО». ПС «МЕДИА» может быть поставлено по дополнительному заказу и включает в себя интерактивный музыкальный редактор с расширенными средствами музыкального макроязыка MML+, а также специальный раздел Библиотеки функций для работы с данными,​ порождёнными при помощи этого музыкального редактора и музыкальными очередями из программ,​ написанных на BDS C в рамках ПС «МАЭСТРО». Кроме того, этот раздел библиотеки включает некоторые дополнительные общесистемные функции,​ не входящие в Библиотеку функций ПС «МАЭСТРО». 
 + 
 +{{anchor:​tape}} 
 +==== Работа с магнитной лентой ==== 
 + 
 +=== ltape() === 
 +<code c> 
 +unsigned ltape(mode, adr, count) 
 +char mode; 
 +unsigned adr, count; 
 +</​code>​ 
 +Загрузить не более ''​count''​ байтов данных с магнитной ленты размещая их в RAM, начиная с адреса ''​adr''​. 
 + 
 +Загрузка может быть прервана по нажатию <​key>​CTRL + STOP</​key>​ или из-за ошибки считывания с магнитной ленты. Мотор включается и выключается автоматически. Возвращается остаточный счётчик. 
 + 
 +Работает в режиме DI(Disable Interrupt). 
 + 
 +Значения для ''​mode'':​ 
 +|0|читать любой тип данных — остановка по счётчику| 
 +|1|CLOAD — остановка по семи подряд идущим нулям или по счётчику| 
 +|2|BLOAD — вычислить значение счётчика исходя из первых 4 байт данных,​ считанных с ленты: start (2 байта),​ end (2 байта)| 
 + 
 +=== dtape() === 
 +<code c> 
 +unsigned dtape(mode, adr, count) 
 +char mode; 
 +unsigned adr, count; 
 +</​code>​ 
 +Записать на магнитную ленту ''​count''​ байтов данных начиная с адреса ''​adr''​. Загрузка может быть прервана по нажатию <​key>​CTRL + STOP</​key>​. Мотор включается и выключается автоматически. Возвращается остаточный счётчик (не 0, если запись была прервана при помощи <​key>​CTRL + STOP</​key>​). 
 + 
 +Работает в режиме DI (Disable Interrupt). 
 + 
 +Значения для ''​mode'':​ 
 +|0|требуется короткий заголовок (пилот-сигнал)| 
 +|1|требуется длинный заголовок (пилот-сигнал)| 
 + 
 +{{anchor:​printer}} 
 +==== Копирование текстового и графического экранов на принтер ==== 
 +=== hcopy0() === 
 +<code c> 
 +hcopy0(firstlin,​ lastlin) 
 +char firstlin, lastlin; 
 +</​code>​ 
 +Копировать на принтер экран начиная со строки ''​firstlin''​ (1…24) и кончая строкой ''​lastlin''​ (1…24) для Screen 0. 
 + 
 +=== hcopy2() === 
 +<code c> 
 +hcopy2() 
 +</​code>​ 
 +Копировать на MSX-принтер весь экран для Screen 2. 
 + 
 +=== lprint() === 
 +<code c> 
 +lprint(adr, count) 
 +unsigned adr; 
 +char count; 
 +</​code>​ 
 +Вывести на принтер ''​count''​ байт начиная с адреса ''​adr''​ непосредственно через [[msx:​dos:​|]] (не используя ''​lprintf()''​ [[bds_c:​bds_c|]]). Эту функцию,​ в том числе, удобно использовать для посылки кодов управления принтером. 
 + 
 +=== lprint2() === 
 +<code c> 
 +lprint2(adr,​ count) 
 +unsigned adr; 
 +char count; 
 +</​code>​ 
 +То же самое, что и ''​[[#​lprint()]]'',​ но все знаки табуляции заменяются на соответствующее (вычисляемое) число пробелов не более 8. 
 + 
 +=== lprintf2() === 
 +<code c> 
 +lprintf2(format,​ args...) 
 +</​code>​ 
 +То же самое, что и ''​lprintf()''​ [[bds_c:​bds_c|]],​ но все знаки табуляции заменяются на соответствующее (вычисляемое) число пробелов не более 8. 
 + 
 +=== ldump() === 
 +<code c> 
 +ldump(sadr, eadr) 
 +unsigned sadr, eadr; 
 +</​code>​ 
 +Дамп ОЗУ с адреса ''​sadr''​ по адрес ''​eadr''​ на принтер. 
 + 
 +==== Дополнительные возможности ==== 
 + 
 +=== blockmem() === 
 +<code c> 
 +unsigned blockmem(blksize) 
 +unsigned blksize; 
 +</​code>​ 
 +Получить количество блоков памяти размером ''​blksize''​ (без выделения этой памяти),​ которое в текущий момент можно разместить в RAM при помощи ''​[[#​alloc()]]''​ или ''​sbrk()''​ 
 + 
 + 
 +:!: Внимание! 
 + 
 +Функция ''​alloc()''​ [[bds_c:​bds_c|]] (в отличие от ''​sbrk()''​) не может выделять память блоками более 32 кбайт — это связано с тем, что одна из переменных в ''​alloc()''​ описана как int вместо unsigned. 
 + 
 +Это ЕДИНСТВЕННАЯ ошибка(?​),​ которую автор Библиотеки обнаружил в [[bds_c:​bds_c|]] v1.50a ​ за более чем три года интенсивной эксплуатации этой системы. Здесь же отметим,​ что ошибочная ситуация со стеком при автоматическом вызове ''​cc2.com''​ из ''​cc.com''​ порождена отличием [[msx:​dos:​|]] 1.03 от [[msx:​cp_m:​|]],​ а не ошибкой [[bds_c:​|]]. 
 +Это отличие компенсировано автором Библиотеки небольшим изменением кода ''​cc.com''​ (вместе с добавлением обнуления счётчиков времени для утилиты [[#​DURATION.COM]]). Изменённую версию ''​cc.com''​ можно идентифицировать по номеру версии,​ выводимому на экран во время выполнения ''​cc.com''​ (v1.50aR вместо v1.50a). 
 + 
 + 
 +=== dump() === 
 +<code c> 
 +dump(sadr, eadr) 
 +unsigned sadr, eadr; 
 +</​code>​ 
 +Дамп ОЗУ с адреса ''​sadr''​ по адрес ''​eadr''​ на экран для Screen 0. 
 + 
 + 
 +=== rwsector() === 
 +<code c> 
 +char rwsector(operation,​ drive, from_sec, count,​buf) 
 +char operaiton, drive, count, *buf; 
 +unsigned from_sec; 
 +</​code>​ 
 +Запись и чтение информации с диска по секторам с возвратом системного кода ошибки (если ошибка имела место при выполнении операции). 
 +|operation|0 — читать \\ 1 — записывать| 
 +|drive| A:0, B:1, C:2, …| 
 +|from_sec|начиная с сектора ''​from_sec''​| 
 +|count|количество подряд идущих секторов (0…255)| 
 +|buf|буфер в памяти для данных| 
 + 
 +Возвращает:​ 
 +|FF|ОК|успешное окончание| 
 +|01|Write Protect|зашита записи| 
 +|02|Not Ready|не готов| 
 +|03|Seek Error|ошибка подвода головки| 
 +|04|Record Not Found|запись не найдена| 
 +|05|Write Error|ошибка записи| 
 +|06|Other Error|другие ошибки| 
 + 
 +__//​Примечание.//​__ 
 +\\ Некоторые ROM, обеспечивающие работу MSX с диском,​могут выдавать коды ошибок,​ несколько отличающиеся от приведённых выше. 
 + 
 +=== speech() === 
 +<code c> 
 +speech(data_adr,​ data_len) 
 +unsigned data_adr, data_len; 
 +</​code>​ 
 +FIXME 
 +Произнести данные,​ подготовленные при помощи программы «Master Voice» Ван дер Путтена. 
 + 
 +=== swapin2() === 
 +<code c> 
 +int swapin2(fname,​ adr, maxlen) 
 +char *fname; 
 +unsigned adr, maxlen; 
 +</​code>​ 
 +Альтернативная версия ''​swapin()''​ [[bds_c:​bds_c|]]. Проверяет размер файла на диске перед загрузкой его в память и сравнивает его с ''​maxlen''​. Возвращает отрицательный размер файла в байтах в случае,​ если его длина превышает ''​maxlen''​ или ERROR (-1) в случае любой ошибки ввода/​вывода. Если файл успешно загружен в память по адресу ''​adr''​ — возвращает длину файла в байтах. 
 + 
 +=== swapout() === 
 +<code c> 
 +int swapout(fname,​ adr, len) 
 +char *fname; 
 +unsigned adr, len; 
 +</​code>​ 
 +Запись данных,​ находящихся по адресу ''​adr''​ длиной ''​len''​ байт в дисковый файл ''​fname''​. Возвращает ERROR (-1) в случае любой ошибки создания/​записи/​закрытия файла (включая переполнение диска). 
 + 
 +===== GRPLIB5 ===== 
 + 
 +Раздел Библиотеки GRPLIB5 (ТОЛЬКО ДЛЯ MSX1) 
 + 
 +ВНИМАНИЕ! Данный раздел библиотеки опирается на терминологию,​ используемую в программе [[msx:​maestro:​pac:​|]]. Для ознакомления с ней рекомендуется изучить её.    
 + 
 +Кроме этого, рекомендуется ознакомиться с описанием утилиты [[#​EDL.COM|Extra Data Linker]] и библиотечной функцией ''​[[#​geteda2()]]''​. 
 + 
 + 
 +=== sprite1() === 
 +<code с> 
 +sprite1(baseplan,​ PAT1, x1, y1, col1, ..., PAT4, x4, y4, col4) 
 +char baseplan, PAT1, PAT2, PAT3, PAT4, x1, y1, x2, y2, x3, y3, x4, y4, col1, col2, col3, col4; 
 +</​code>​ 
 +Функция,​ аналогичная ''​[[#​sprite()]]'',​ но имеющая прямое управление цветом спрайта ([[msx:​msx_1|MSX1]]) и выводящая не более 4 спрайтов одновременно. В случае,​ если используется менее 4 спрайтов — записывается 0 вместо ''​PAT2…PAT4''​ после цвета последнего использованного спрайта. 
 + 
 +=== sprcol1() === 
 +<code с> 
 +sprcol1(plane,​ colr) 
 +char plane, colr; 
 +</​code>​ 
 +Изменить цвет плана спрайта. 
 + 
 +=== prtscrnt() === 
 +<code с> 
 +prtscrnt() 
 +</​code>​ 
 +Вывести на принтер шестнадцатеричный дамп всей текущей Name Table для отладки. 
 + 
 +{{anchor:​graphics_text_windows}} 
 +==== Графические и текстовые окна для полиэкрана ==== 
 + 
 +=== gameini() === 
 +<code c> 
 +gameini(MNTfile,​ screensX, screensY, LIBfile, SPRfile, sprsize, magn, mode) 
 +char *MNTfile, *LIBfile, *SPRfile, screensX, screensY, sprsize, magn, mode; 
 +</​code>​ 
 +Назначение:​ стандартная инициализация игровой программы. 
 + 
 +Распределение RAM для MNT (Multi-screen Name Table) при помощи ''​[[#​sbrk()]]'',​ установка Screen 2, заполнение Name Table экрана нулями,​ установка параметров gwindow (графического окна) по максимальному размеру экрана 30×22, загрузка таблицы перекодировки для стандартного расположения алфавитно-цифровых паттернов в библиотеке и загрузка файлов MNT, LIB и SPR в абсолютном некомпрессированом формате с диска, если не найдены соответствующие компрессированые файлы с ТЕМИ ЖЕ ИМЕНАМИ. Файлы LIB и SPR могут быть прикомпонованы к концу области External (''​-f''​),​ а MNT - к концу кода (''​-c''​). Файлы LIB и SPR переписываются непосредственно в VRAM и могут более не перезагружаться,​ а MNT загружается с диска или расширяется из компрессированого формата в область,​ предварительно зарезервированную при помощи ''​[[#​sbrk()]]''​ после того, как файлы LIB и SPR уже переписаны в VRAM. Если вместо SPR-файла написан 0 — соответствующая область VRAM для спрайтов заполняется из файла LIB с рекомпозицией формата LIB в SPR (16×16). 
 + 
 +Параметры:​ 
 +|''​screenX'',​ ''​screenY''​|размеры MNT. Должны совпадать с размерами,​ указанными при создании и сохранении MNT при помощи [[msx:​maestro:​pac:​|]] — в противном случае диагностируется ошибка| 
 +|''​sprsize''​|SIZE_8 или SIZE_16| 
 +|''​magn''​|MAGNIFIED или UNMAGNIFIED| 
 +|''​mode''​|SINGLE или SIMULTANEOUS| 
 + 
 +Последние три параметра аналогичны параметрам функции ''​[[#​sprctl()]]''​. 
 + 
 +Внутри функции ''​[[#​gameini()]]''​ производится автоматический вызов ''​[[#​grpini()]]'',​ ''​[[#​lodlib()]]'',​ ''​[[#​lodmnt()]]''​ и др. 
 + 
 +=== gameini2() === 
 +<code c> 
 +gameini2(screensX,​ screensY, sprsize, magn, mode) 
 +char screensX, screensY, sprsize, magn, mode; 
 +</​code>​ 
 +Назначение:​ то же самое, что и ''​[[#​gameini()]]'',​ но данная функция НЕ ЗАГРУЖАЕТ файлы LIB, SPR и MNT. Вы должны сами вызывать функции ''​[[#​lodlib()]]''​ и ''​[[#​lodmnt()]]''​ в явном виде. Это даёт возможность компрессировать/​не компрессировать (по вашему усмотрению) данные в файлах,​ присваивать компрессированым файлам имена, отличные от некомпрессированых файлов,​ перезагружать эти файлы перед началом каждого повторяющегося исполнения вашей программы и пр. Кроме того, это даёт Вам возможность по-разному прикомпоновывать файлы LIB, SPR и MNT в зависимости от организации вашей программы. 
 + 
 +Примечание. Автором обычно используется следующее правило для размещения и прикомпоновки различных данных:​ 
 +  * данные,​ которые перемещаются в VRAM и в дальнейшем не подвергаются там модификации,​ прикомпоновываются к концу области External (''​-f''​ [[#​EDL.COM|EDL]]) с тем, чтобы после загрузки их в VRAM, эта область памяти освобождалась для размещения рабочих областей,​ переменных и пр. 
 +  * данные,​ которые могут подвергаться модификации,​ прикомпоновываются к концу кода (до начала области External) в компрессированом или некомпрессированом формате и экспандируются/​переписываются в рабочую область RAM (в том числе в те адреса,​ которые освободились после загрузки данных,​ прикомпонованых с ''​-f'',​ в VRAM) перед началом каждого повторяющегося выполнения программы. 
 + 
 +=== clrscr() === 
 +<code c> 
 +clrscr(SCRline,​ SCRcolumn, width, height) 
 +char SCRline, SCRcolumn, width, height; 
 +</​code>​ 
 +Очистить прямоугольный участок экрана в Scrеen 2 с координатой левого верхнего угла ''​SCRline''​ (0…23 по Y) и ''​SCRcolumn''​ (0…31 по X), шириной width (1…32) и высотой ''​height''​ (1…24), заполнив соответствующие байты Name Table экрана нулями. 
 + 
 +=== gopen() === 
 +<code c> 
 +gopen(libbase,​ framtop, framleft, framwidth, framheight) 
 +char libbase, framtop, framleft, framwidth, framheight;​ 
 +</​code>​ 
 +Открыть Graphic Window (Графическое Окно): нарисовать рамку, очистить содержимое и запомнить координаты окна в системной рабочей области для использования их в дальнейшем функцией ''​[[#​gwind()]]''​ 
 + 
 +''​libbase''​ является номером паттерна в библиотеке знакомест (0…249), начиная с которого располагаются 6 паттернов рамки: 4 паттерна для углов, горизонтальная линия и вертикальная линия. Если вы используете стандартную библиотеку знакомест,​ то можете указывать в качестве ''​libbase''​ ключевые слова ''​STD_RED''​ и ''​STD_BLUE''​. 
 + 
 +Параметры ''​framtop''​ и ''​framleft''​ задают координаты верхнего левого угла рамки, а ''​framwidth''​ и ''​framheight''​ — её ширину и высоту. 
 + 
 + 
 +=== topen() === 
 +<code c> 
 +topen(libbase,​ framtop, framleft, framwidth, framheight) 
 +char libbase, framtop, framleft, framwidth, framheight;​ 
 +</​code>​ 
 +Открыть Text Window (Текстовое Окно со скроллингом текста) для использования функции tprintf(). 
 + 
 +Параметры аналогичны параметрам ''​[[#​gopen()]]''​. 
 + 
 +=== gdef() === 
 +<code c> 
 +gdef(windline,​ windcolumn, windwidth, windheight) 
 +char windline, windcolumn, windwidth, windheight;​ 
 +</​code>​ 
 +Определить параметры Graphic Window, но не рисовать рамку и не очищать содержимое окна. 
 + 
 +Используется внутри ''​[[#​gopen()]]''​. 
 + 
 +=== tdef() === 
 +<code c> 
 +tdef(windline,​ windcolumn, windwidth, windheight) 
 +char windline, windcolumn, windwidth, windheight;​ 
 +</​code>​ 
 +Определить параметры Text Window, но не рисовать рамку и не очищать содержимое окна.  
 +Используется внутри ''​[[#​topen()]]''​. 
 + 
 +=== gframe() === 
 +<​code>​ 
 +gframe(libbase) 
 +char libbase; 
 +</​code>​ 
 +Нарисовать/​перерисовать рамку с очисткой окна для уже открытого или определённого графического окна. 
 + 
 +{{anchor:​direct_io_polyscreen}} 
 +==== Прямой ввод/​вывод для полиэкрана ==== 
 + 
 +=== absntab() === 
 +<code c> 
 +unsigned absntab(y, x) 
 +unsigned y, x; 
 +</​code>​ 
 +Получить абсолютный адрес внутри VRAM Name Table по двум координатам экрана ''​y''​ (0…23) и ''​x''​ (0…31). 
 + 
 +=== absptab() === 
 +<code c> 
 +unsigned absptab(y, x) 
 +unsigned y, x; 
 +</​code>​ 
 +Получить абсолютный адрес внутри первого из трёх VRAM Pattern Generator Table по двум координатам паттерна ''​y''​ (0…7) и ''​x''​ (0…32) 
 + 
 +=== absctab() === 
 +<​code>​ 
 +unsigned absctab(y, x) 
 +unsigned y, x; 
 +</​code>​ 
 +Получить абсолютный адрес внутри первого из трёх VRAM Colour Table по двум координатам паттерна ''​y''​ (0…7) и x (0…32) 
 + 
 +=== *absmntab() === 
 +<code c> 
 +char *absmntab(y,​ x) 
 +unsigned y, x; 
 +</​code>​ 
 +Получить абсолютный адрес внутри MNT по координатам ''​y''​ и ''​x''​. Максимальные значения этих координат зависят от конфигурации и размеров MNT. 
 + 
 +=== lodlib() === 
 +<code c> 
 +lodlib(LIB_link,​ SPR_link, base, LIB_file, SPR_file) 
 +char *LIB_file, *SPR_file, *LIB_link, *SPR_link;​ 
 +unsigned base; 
 +</​code>​ 
 +Экспандировать и загрузить прикомпонованые и компрессированые файлы LIB и SPR в VRAM: 
 +  * ''​LIB_link''​ и ''​SPR_link''​ — имена этих файлов,​ 
 +  * ''​base''​  
 +    * ''​codend()''​ для ''​-c'',​  
 +    * ''​endext()''​ для ''​-f''​ 
 +    * 0, если Extra Data не используется (в этом случае не производится попытки найти ''​LIB_link''​ и ''​SPR_link''​) 
 + 
 +Если ''​LIB_link''​ или ''​SPR_link''​ не найдены в Extra Data, производится попытка загрузки с диска НЕКОМПРЕССИРОВАНЫХ файлов ''​LIB_file''​ и ''​SPR_file''​ (с диагностикой соответствующих ошибок ввода/​вывода). 
 + 
 +Если вместо ''​SPR_link''​ или ''​SPR_file''​ написан 0 — в качестве данных для Sprite Generator Table используется LIB_link или LIB_file с соответсвующей рекомпозицией паттернов к размеру спрайтов 16×16. 
 + 
 +=== lodmnt() === 
 +<code c> 
 +lodmnt(MNT_link,​ base, MNT_file) 
 +char *MNT_link, *MNT_file;​ 
 +unsigned base; 
 +</​code>​ 
 +Экспандировать и загрузить прикомпонованый и компрессированый файл MNT в абсолютном формате — F7 (подробнее о форматах [[msx:​maestro:​pac:​pac#​files-formats|здесь]]) в RAM (предварительно выделенный при помощи ''​[[#​gameini()]]''​ или ''​[[#​gameini2()]]''​). ''​base''​ используется аналогично ''​[[#​lodlib()]]''​. Если ''​base''​ равно нулю или файл ''​MNT_link''​ не найден в Extra Data — производится загрузка НЕКОМПРЕССИРОВАНОГО файла ''​MNT_file''​ с диска. После этого загружается стандартная таблица перекодировки. 
 + 
 +=== lodlib2 === 
 +<code c> 
 +lodlib2(LIB_link,​SPR_link,​base) 
 +char *LIB_file,​*SPR_file;​ 
 +unsigned base; 
 +</​code>​ 
 +Сокращённая версия ''​[[#​lodlib()]]''​ без загрузки файлов с диска. 
 +Экспандировать прикомпонованые и компрессированые LIB и SPR файлы в VRAM: 
 +  * ''​LIB_link''​ и ''​SPR_link''​ — имена этих файлов,​ 
 +  * ''​base''​ — ''​codend()''​ для ''​-c''​ 
 +  * ''​endext()''​ для ''​-f''​ 
 +Если вместо SPR_link написан 0 — в качестве данных для Sprite Generator Table используются данные из ''​LIB_link''​ с соответствующей рекомпозицией паттернов к размеру спрайтов 16×16. 
 +  
 +=== bwind() === 
 +<code c> 
 +bwind(MNTline,​ MNTcolumn, framtop, frambottom) 
 +unsigned MNTline, MNTcolumn;​ 
 +char framtop, frambottom;​ 
 +</​code>​ 
 +Block Winlow: вывести блок из MNT с координатами верхнего левого угла ''​MNTline''​ (Y), ''​MNTcolumn''​ (X) на экран начиная со строки экрана ''​framtop''​ (верхняя строка) и кончая строкой экрана ''​frambottom''​ (нижняя строка). 
 + 
 +Ширина блока: всегда 32 знакоместа. 
 + 
 +Для данного типа окна не предусмотрены операции OPEN/DEFINE и рамка. 
 + 
 +Этот тип окна имеет максимальную скорость отображения данных из MNT на физический экран. 
 + 
 +=== gwind() === 
 +<code c> 
 +gwind(MNTline,​ MNTcolumn) 
 +unsigned MNTline, MNTcolumn;​ 
 +</​code>​ 
 +Graphic Window: вывести блок из MNT с координатами верхнего левого угла ''​MNTline''​ (Y), ''​MNTcolumn''​ (X) на экран в область,​ предварительно определённую при помощи ''​[[#​gopen()]]''​ или ''​[[#​gdef()]]''​. 
 + 
 +=== swind() === 
 +<code c> 
 +swind(MNTline,​ MNTcolumn, SCRline, SCRcolumn, width, height) 
 +unsigned MNTline, MNTcolumn;​ 
 +char SCRline, SCRcolumn, height, width; 
 +</​code>​ 
 +Sub-Window: вывести блок из MNT с координатами верхнего левого угла ''​MNTline''​ (Y), ''​MNTcolumn''​ (X) на экран в область с координатами верхнего левого угла ''​SCRline''​ (0…23 по Y), ''​SCRcolumn''​ (0…31 по X). 
 + 
 +Ширина и высота выводимого блока: ''​width''​ (1…32) и ''​height''​ (1…24). 
 + 
 +Для данного типа окна не предусмотрены операции OPEN/​DEFINE. Рамка может быть специально нарисована при помощи ''​[[#​sframe()]]''​. 
 + 
 +=== sframe() === 
 +<code c> 
 +sframe(libbase,​ SCRline, SCRcolumn, width, height) 
 +char libbase, SCRline, SCRcolumn, width, height; 
 +</​code>​ 
 +Нарисовать рамку и очистить область внутри неё нулями. 
 + 
 +Параметры аналогичны параметрам ''​[[#​gopen()]]''​. 
 + 
 +=== putchr() === 
 +<code c> 
 +putchr(SCRline,​ SCRcolumn, c) 
 +char SCRline, SCRcolumn, c; 
 +</​code>​ 
 +Вывести символ ''​c''​ на экран (непосредственно в VRAM Name Table) без перекодировки в позиции ''​SCRline''​ (0…23) и ''​SCRcolumn''​ (0…31). 
 + 
 +=== getchr() === 
 +<code c> 
 +char getchr(SCRline,​ SCRcolumn) 
 +char SCRline, SCRcolumn;​ 
 +</​code>​ 
 +Взять символ (байт) с экрана (непосредственно из VRAM Name Table) находящийся в позиции ''​SCRline''​ (0…23) и ''​SCRcolumn''​ (0…31). 
 + 
 +=== putstr() === 
 +<code c> 
 +putstr(SCRline,​ SCRcolumn, str, len) 
 +char SCRline, SCRcolumn, *str, len; 
 +</​code>​ 
 +Вывести строку ''​str''​ длиной ''​len''​ на экран без перекодировки в позиции ''​SCRline''​ (0…23) и ''​SCRcolumn''​ (0…31). 
 + 
 +=== putstrt() === 
 +<​code>​ 
 +putstrt(SCRline,​ SCRcolumn, str) 
 +unsigned SCRline, SCRcolumn;​ 
 +char *str; 
 +</​code>​ 
 +То же самое, что ''​[[#​putstr()]]'',​ но строка автоматически перекодируется перед выводом на экран с использованием стандартной таблицы перекодировки и должна оканчиваться двоичным нулём. 
 + 
 +Внимание! Компилятор [[bds_c:​bds_c|BDS C]] гасит старший бит во всех литеральных строках и, поэтому буквы кириллического алфавита не будут сохраняться в генерируемом коде (они будут транслитерированы в латинские). Для решения этой проблемы без модификации компилятора рекомендуются следующие приёмы:​ 
 +  - Хранить все русскоязычные сообщения в MNT и выводить их на экран при помощи [[#​putstr()]] или [[#​swind()]]. 
 +  - Хранить все русскоязычные сообщения в отдельном файле ASCII, подготовленном при помощи текстового редактора,​ и, перед выполнением программы,​ загружать его в память. \\ После этого может быть использована функция ''​[[#​putstrt()]]''​. 
 +  - Записывать все кириллические символы внутри литеральных строк программы при помощи восьмеричных констант. Для этой цели можно воспользоваться утилитой [[#​DUMP.COM]],​ входящей в состав ПС «МАЭСТРО». 
 + 
 +Следует заметить,​ что первые два приёма являются наиболее предпочтительными и при использовании любых других компиляторов,​ в том числе, не подавляющих кириллические символы. Это связанно с тем, что таким образом обеспечивается дополнительная независимость программы от данных и свобода в изменении диалога,​ ведущегося программой (в том числе, перевод его на другой язык) без изменения и перекомпиляции самой программы. 
 + 
 +=== tframe() === 
 +<code c> 
 +tframe(libbase) 
 +char libbase; 
 +</​code>​ 
 +Нарисовать/​перерисовать рамку с очисткой окна для уже открытого или определённого при помощи ''​[[#​topen()]]''​ / ''​[[#​tdef()]]''​ текстового окна. 
 + 
 +=== tprintf() === 
 +<code c> 
 +tprintf(format) 
 +char *format; 
 +</​code>​ 
 +Форматированный вывод в предварительно открытое или определённое текстовое окно с перекодировкой. Параметры такие же, как у функции ''​printf()''​ [[bds_c:​bds_c|]]. Внутри окна производится локальный скроллинг текста. 
 + 
 +{{anchor:​work_polyscreen}} 
 +====  Управление знакоместным полиэкраном ==== 
 + 
 +=== stornt() === 
 +<code с> 
 +stornt(SCRline,​ SCRcolumn, width, height, buf) 
 +char   ​SCRline,​ SCRcolumn, width, height, *buf; 
 +</​code>​ 
 +Сохранить блок с экрана (из VRAM Name Table) в RAM для последующего восстановления при помощи ''​[[#​restnt()]]''​ или ''​[[#​restnt2()]]''​. Размер буфера ''​buf''​ для сохранения блока должен быть не меньше произведения размеров блока ''​width''​ × ''​height''​. 
 + 
 +=== restnt() === 
 +<​code>​ 
 +restnt(SCRline,​ SCRcolumn, width, height, buf) 
 +char   ​SCRline,​ SCRcolumn, width, height, *buf; 
 +</​code>​ 
 +Восстановить блок, сохранённый при помощи ''​[[#​stornt()]]'',​ на экране (в VRAM Name Table). Первой восстанавливается верхняя строка блока. 
 + 
 +Параметры аналогичны параметрам ''​[[#​stornt()]]''​. 
 + 
 +=== restnt2() === 
 +<code c> 
 +restnt2(SCRline,​ SCRcolumn, width, height, buf) 
 +char SCRline, SCRcolumn, width, height, *buf; 
 +</​code>​ 
 +Восстановить блок, сохранённый при помощи ''​[[#​stornt()]]'',​ на экране (в VRAM Name Table). Первой восстанавливается нижняя строка блока. 
 + 
 +Параметры аналогичны параметрам ''​[[#​stornt()]]''​. 
 + 
 +=== getchrm() === 
 +<code c> 
 +char getchrm(SCRlin,​ SCRcol, gwbaseY, gwbaseX) 
 +char SCRlin ,SCRcol; 
 +unsigned gwbaseY, gwbaseX; 
 +</​code>​ 
 +Взять символ из MNT, отражённый на экран при помощи ''​[[#​gwind()]]''​ с координатами левого верхнего угла (''​gwbaseY'',''​gwbaseX''​),​ пользуясь для этого координатами экрана,​ а не координатами MNT. 
 + 
 +=== putchrm() === 
 +<code c> 
 +putchrm(SCRlin,​ SCRcol, gwbaseY, gwbaseX, c) 
 +char SCRlin, SCRcol, c; 
 +unsigned gwbaseY, gwbaseX; 
 +</​code>​ 
 +Поместить символ ''​c''​ в MNT, пользуясь для этого координатами экрана аналогично ''​[[#​getchrm()]]''​. 
 + 
 +=== st_swind() === 
 +<code c> 
 +st_swind(MNTline,​ MNTcolumn, SCRline, SCRcolumn, width, height, buf) 
 +unsigned MNTline, MNTcolumn;​ 
 +char SCRline,​SCRcolumn,​width,​height,​*buf;​ 
 +</​code>​ 
 +Функция ''​[[#​swind()]]''​ с предварительным сохранением изменяемой части экрана в буфере ''​buf''​. Комбинация ''​[[#​stornt()]]''​ и ''​[[#​swind()]]''​. 
 + 
 +===== Дополнительные объекты из GRPLIB0.H ===== 
 + 
 +Дополнительные макро-функции и некоторые системные переменные общего пользования из заголовка GRPLIB0.H 
 +=== MSX2 === 
 +<code c> 
 +MSX2 
 +</​code>​ 
 +Системная переменная (устанавливается ''​[[#​grpini()]]''​ при инициализации) TRUE, если ваш компьютер — [[msx:​msx_2|MSX2]] 
 + 
 +=== VRAM_128 === 
 +<code c> 
 +VRAM_128 
 +</​code>​ 
 +Системная переменная (устанавливается ''​[[#​grpini()]]''​ при инициализации) TRUE, если у вашего компьютера 128 кбайт VRAM. 
 + 
 +=== MEMORY_MAPPER === 
 +<code c> 
 +MEMORY_MAPPER 
 +</​code>​ 
 +Системная переменная (устанавливается ''​grpini()''​ при инициализации) TRUE, если у вашего компьютера есть аппаратура [[msx:​ram:​ram#​mapper|Memory Mapper]]. 
 + 
 +=== TEXTWIDTH() === 
 +<code c> 
 +TEXTWIDTH(width) 
 +/* macro */ 
 +</​code>​ 
 +Установить максимальную ширину текстовой строки width для Screen 0. 
 + 
 +=== MOUSE1() === 
 +<code с> 
 +MOUSE1(x, y) 
 +/* macro */ 
 +</​code>​ 
 +Записать в переменные ''​x'',''​y''​ относительные приращения координат мыши, подключённой к порту 1. 
 + 
 +=== MOUSE2() === 
 +<code с> 
 +MOUSE2(x, y) 
 +/* macro */ 
 +</​code>​ 
 +Записать в переменные ''​x'',''​y''​ относительные приращения координат мыши, подключённой к порту 2. 
 + 
 +=== USE_MOUSE() === 
 +<code c> 
 +USE_MOUSE(mouse_num) 
 +/* macro */ 
 +</​code>​ 
 +Альтернативный метод опроса мыши: активация специального процесса,​ вызываемого из ''​[[#​totick()]]''​. Этот процесс вычисляет абсолютные координаты мыши (0…511 или 0…256 для экранов с низким разрешением) каждый «тик» и помещает их в системные переменные ''​[[#​MOUSE_X]]'',​ ''​[[#​MOUSE_Y]]''​ (абсолютные координаты) и ''​[[#​RMOUSE_X]]'',​ ''​[[#​RMOUSE_Y]]''​ (относительные координаты). 
 + 
 +Только одна мышь (''​mouse_num''​ 1 или 2) может опрашиваться этим процессом.  
 + 
 +''​[[#​UNUSE_MOUSE]]''​ деактивирует этот процесс (установлен по умолчанию). Этот процесс не зависит от ''​[[#​TICKON]]''​ / ''​[[#​TICKOFF]]''​ и ''​TICKSTART''​ / ''​TICKSTOP''​ 
 + 
 +=== UNUSE_MOUSE === 
 +<code c> 
 +UNUSE_MOUSE 
 +/* macro */ 
 +</​code>​ 
 +Деактивация механизма ''​[[#​USE_MOUSE()]]''​ 
 + 
 +=== MOUSE_X === 
 +<code c> 
 +MOUSE_X 
 +</​code>​ 
 +Системная переменная 
 + 
 +Вы можете написать,​ например:​ 
 +<code c> 
 +x=MOUSE_X;​ 
 +</​code>​ 
 +для получения абсолютной Х–координаты мыши, если активирован ''​[[#​USE_MOUSE]]'',​ а также присвоить этой переменной значение координаты Х для программного позиционирования курсора <code c>​MOUSE_X=x;</​code>​ 
 + 
 +=== MOUSE_Y === 
 +<code c> 
 +MOUSE_Y 
 +</​code>​ 
 +Системная переменная 
 + 
 +Вы можете написать,​ например:​ 
 +<code c> 
 + ​y=MOUSE_Y;​ 
 +</​code>​ 
 +для получения абсолютной Y–координаты мыши, если активирован ''​[[#​USE_MOUSE]]'',​ а также присвоить этой переменной значение координаты Y для программного позиционирования курсора <code c>​MOUSE_Y=y;</​code>​ 
 + 
 +=== RMOUSE_X === 
 +<code c> 
 +RMOUSE_X 
 +</​code>​ 
 +Системная переменная 
 + 
 +То же самое для относительной координаты X. 
 + 
 +=== RMOUSE_Y === 
 +<code c> 
 +RMOUSE_Y 
 +</​code>​ 
 +Системная переменная 
 + 
 +То же самое для относительной координаты Y. 
 + 
 + 
 +=== _picture === 
 +FIXME 
 +<code c> 
 +_picture 
 +</​code>​ 
 +Системная переменная 
 + 
 +Значение по умолчанию:​ TRUE 
 + 
 +=== GETTIME() === 
 +<code c> 
 +GETTIME(h, m, s) 
 +/* macro */ 
 +</​code>​ 
 +Записать текущее значение часов, минут и секунд в переменные ''​h'',​ ''​m''​ и ''​s''​ соответственно. 
 + 
 +=== GETDATE() === 
 +<code c> 
 +GETDATE(y, m, d) 
 +/* macro */ 
 +</​code>​ 
 +Записать текущее значение года, месяца и дня в переменные ''​y'',​ ''​m''​ и ''​d''​ соответственно. 
 + 
 +=== DIS_INTERRUPT === 
 +<code c> 
 +DIS_INTERRUPT 
 +/* macro */ 
 +</​code>​ 
 +Выполнить команду Z80 DI (Disable Interrupt) 
 + 
 + 
 +=== ENA_INTERRUPT === 
 +<code c> 
 +ENA_INTERRUPT 
 +/* macro */ 
 +</​code>​ 
 +Выполнить команду Z80 EI (Enable Interrupt) 
 + 
 +=== DIS_SCREEN === 
 +<code c> 
 +DIS_SCREEN 
 +/* macro */ 
 +</​code>​ 
 +Запретить вывод на экран (Disable Screen) 
 + 
 +=== ENA_SCREEN === 
 +<code c> 
 +ENA_SCREEN 
 +/* macro */ 
 +</​code>​ 
 +Разрешить вывод на экран (Enable Screen) 
 + 
 +=== EXIT === 
 +<code c> 
 +EXIT 
 +/* macro */ 
 +</​code>​ 
 +FIXME Выход в [[msx:​dos:​|]] с восстановлением Screen 0 и параметров цвета экрана из энергонезависимой памяти MSX2 или GRPMSX1.H MSX1 
 + 
 +=== PAUSE() === 
 +<code с> 
 +PAUSE(beep_num) 
 +/* macro */ 
 +</​code>​ 
 +Подача ''​beep_num''​ звуковых сигналов и ожидание нажатия клавиши <​key>​SHIFT</​key>​ с периодическим обращением к ''​[[#​totick()]]''​. Используется для отладки программ,​ работающих с графическими экранами. 
 + 
 +=== DUMP() === 
 +<code c> 
 +DUMP(msg, sadr, eadr) 
 +/* macro */ 
 +char *msg; 
 +unsigned sadr, eadr; 
 +</​code>​ 
 +Вывести на текстовой экран (Screen 0) идентификационное сообщение ''​msg''​ и шестнадцатеричный дамп памяти начиная с ''​sadr''​ и кончая ''​eadr''​ 
 + 
 +=== GDUMP() === 
 +<code c> 
 +GDUMP(fg, bg, msg, sadr, eadr) 
 +/* macro */ 
 +char fg, bg, *msg; 
 +unsigned sadr, eadr; 
 +</​code>​ 
 +Вывести на графический экран (Screen 5…8) идентификационное сообщение ''​msg''​ и шестнадцатеричный dump памяти начиная с ''​sadr''​ и кончая ''​eadr''​ 
 + 
 +''​fg''​ и ''​bg''​ — палитры для переднего и заднего плана соответственно.  
 + 
 +Начальная позиция:​ левый верхний угол экрана. 
 + 
 +=== DIR_GET_CHAR === 
 + 
 +<code c> 
 +DIR_GET_CHAR 
 +/* macro */ 
 +</​code>​ 
 + 
 +DIR_PUT_CHAR 
 +<code c> 
 +DIR_PUT_CHAR 
 +/* macro */ 
 +</​code>​ 
 +FIXME Напишите эти два макровызова вне тела главной программы и других функций (это компилируемые переопределения функций ''​[[#​getchar()]]''​ и ''​[[#​putchar()]]''​) и ВЕСЬ консольный ввод/​вывод будет направлен непосредственно через ROM BIOS вместо [[msx:​bdos|BDOS]] — это гарантирует отсутствие проверки на ''​^C''​ и другие специальные коды (''​^S'',​ ''​^P'',​ ...) и, кроме того, несколько быстрее. 
 + 
 +=== INKEY === 
 +<code c> 
 +INKEY 
 +/* macro */ 
 +</​code>​ 
 +FIXME Функция,​ аналогичная ''​inkey$''​ языка Бейсик.  
 + 
 +Напишите:​ 
 +<code c> 
 +c = INKEY; 
 +</​code>​ 
 +и вы получите код символа,​ введённого с консоли или 0, если ни одна клавиша не была нажата. Эта функция работает через [[msx:​bdos|BDOS]] 6 — нет ожидания,​ нет проверки на ''​^C''​ и другие специальные коды, нет отображения символа на экран. 
 + 
 +=== VARPARMS === 
 +<code c> 
 +VARPARMS(first_arg_in_list) 
 +/* macro */ 
 +</​code>​ 
 +Напишите ''​VARPARMS''​ внутри любой функции сразу после описаний внутренних переменных функции,​ если таковые имеются,​ (''​VARPARMS''​ является выполняемым макросом) и используйте после этого ''​PARM(n)''​ для извлечения параметра функции по его номеру ''​n''​ (первый параметр имеет номер 0).  
 + 
 +Пример:​ 
 +<code c> 
 +main() 
 +
 +  foo(1, "​txt"​);​ 
 +
 + 
 +foo(arglist) 
 +unsigned arglist; /* '​arglist'​ used for argaddr extraction */ 
 +
 +  char zot; 
 +  VARPARMS(arglist) 
 +  printf("​%d %s", PARM(0), PARM(1)); 
 +
 +</​code>​ 
 +В результате выполнения данной программы будет напечатано:​ 
 +<​code>​ 
 +1 txt 
 +</​code>​ 
 + 
 +=== PARM() === 
 +<code c> 
 +PARM(n) 
 +/* macro */ 
 +</​code>​ 
 +Используется для извлечения параметра функции по номеру n вместе с макросом ''​[[#​VARPARMS]]''​ 
 + 
 +Первый параметр в списке имеет номер 0 
 + 
 +Номер ''​n''​ может быть переменной. 
 + 
 +=== KBDOFF === 
 +<code c> 
 +KBDOFF 
 +/* macro */ 
 +</​code>​ 
 +отключить опрос клавиатуры и обработку прерываний в BIOS 
 + 
 +=== KBDON === 
 +<code c> 
 +KBDON 
 +/* macro */ 
 +</​code>​ 
 +включить опрос клавиатуры и обработку прерываний в BIOS 
 + 
 +=== KBDRESTORE === 
 +<code c> 
 +KBDRESTORE 
 +/* macro */ 
 +</​code>​ 
 +восстановить опрос клавиатуры и обработку прерываний в BIOS 
 + 
 +{{anchor:​grplib_n4}} 
 +===== Рекомендации по использованию и форматы данных ===== 
 + 
 +  - Внимание! <code c>#​include grplib0.h</​code>​ или <code c>#​include grpmsx1.h</​code>​ обязательно должны присутствовать в качестве самой первой строки (не считая комментариев) в вашей программе,​ использующей Библиотеку! (''​bdscio.h''​ вызывается автоматически из ''​grplib0.h''​). Эти заголовки содержат рабочие области и макроопределения,​ абсолютно необходимые для нормальной работы функций Библиотеки. 
 +  - Одна из функций [[#​grpini()]],​ [[#​gameini()]] или [[#​gameini2()]] обязательно должна быть выполнена до обращения к другим функциям Библиотеки. \\ Эти функции инициализируют рабочую область Библиотеки и устанавливают стандартные значения "по умолчанию"​. 
 +  - Имена, начинающиеся с подчеркивания "​_"​ зарезервированы для системного использования. 
 +  - Так как некоторые процессы могут пользоваться одними и теми же системными ресурсами (Графический аккумулятор,​ аккумулятор позиций текстового курсора,​ шаг печати для графических экранов и др.) — обращайте особое внимание на то, чтобы не использовать значения,​ которые остаются и сохраняются в таких ресурсах — они могут быть оставлены другим процессом при мультизадачной работе! 
 +  - Область External НИКОГДА НЕ ДОЛЖНА НАХОДИТЬСЯ НА СТРАНИЦАХ 0 и 3 (адреса памяти 0...0x3FFF и 0xC000...0xFFFF) RAM. Используйте ''​-e4000''​ для ''​cc''​ и ''​clink''​ как минимум! Это связано с тем, что механизм работы со слотами и мэппером,​ реализованый в Библиотеке,​ находится в External и может работать только в страницах 1 или 2 (в отличие от оригинального механизма [[msx:​bios|MSX ROM BIOS]], который работает некорректно и при некоторых межслотовых вызовах сам себя выбрасывает из памяти). 
 +  - Если вы хотите вызывать [[msx:​bios|BIOS]] или [[msx:​bios#​subrom|SubROM]] сами (механизм вызова описан в GRPLIB0.H) — никогда не передавайте в них указатели на данные,​ которые могут оказаться в странице 0 (например на литеральные строки из текста программы,​ находящейся в RAM). \\ Это связано с тем, что во время работы [[msx:​bios|BIOS]] или [[msx:​bios#​subrom|SubROM]] страницу 0 занимает сам ROM (библиотечные функции в подобных случаях предварительно буферизируют данные в стеке). 
 +  - Ниже приводится описание «компрессированного» формата данных,​ который используется в некоторых библиотечных функциях. \\ Компрессия достигается за счёт сжатия «однородностей» — одинаковых слов, идущих последовательно друг за другом. \\ Алгоритм неадаптивный,​ т.е. ориентированный на фиксированную длину слова — в данном случае 1 байт. \\ Компрессированые данные состоят из элементов данных,​ каждый из которых в свою очередь,​ состоит из «признака»,​ «счётчика» и «данных». «Признак» занимает один бит и означает компрессию (1) или обычную последовательность данных (0). «Счётчик» занимает 7 бит. «Данные» представляют собой один байт (в случае компрессии) или от 1 до 127 байт в случае «некомпрессируемой» последовательности байтов. Таким образом,​ «элементы» могут выглядеть следующим образом:​ <​code>​ 
 +   0-й байт ​  1-й байт 
 +┌───────────┬──────────┐ 
 +│ 1xxx xxxx │zzzz zzzz │ повторение байта 'zzzz zzzz' 'xxx xxxx' (0…127) раз 
 +└───────────┴──────────┘ 
 + 
 +   0-й байт ​  1-й байт ​         N-й байт 
 +┌───────────┬──────────┬─────┬───────────┐ 
 +│ 0xxx xxxx │yyyy yyyy │ ... │ zzzz zzzz │ N (xxx xxxx) байт для «прямого» копирования 
 +└───────────┴──────────┴─────┴───────────┘ 
 +   0-й байт 
 +┌───────────┐ 
 +│ 0000 0000 │ «больше нет данных» 
 +└───────────┘ 
 +</​code>​ Изображения в формате COPY (Data) для Screen 5…8 имеют заголовки из двух слов (по 2 байта каждое слово) с указанием ширины и высоты изображения в точках. Для компрессированых изображений ширина (1-е слово) записывается в отрицательном виде, т.е. -ширина. \\ Этот признак используется функциями Библиотеки для автоматического распознавания компрессированого формата изображения. Отрицательная ширина может быть установлена при помощи утилиты Picture Compressor — [[#​PICO.COM]]. \\ Другие данные,​ не имеющие таких заголовков,​ могут быть компрессированы или расширены при помощи утилиты Files Compressor/​Expander — [[#​FCX.COM]] и библиотечной функции [[#​expand()]]. 
 +  - Внимательно ознакомьтесь с файлами ''​GRPLIB0.H''​ и ''​GRPMSX1.H''​ — они содержат много полезной информации и дополнительных ключевых слов для использования в текстах ваших программ. Будьте осторожны — не переназначайте имена системных переменных! 
 + 
 +===== Работа с портами джойстика ===== 
 +Если вы хотите опрашивать порты джойстика для того чтобы с ними можно было работать одновременно с опросом клавиш курсора,​ пробела (триггер 1) и клавишей <​key>​GRAPH</​key>​ (триггер 2), добавьте дополнительный ''#​include''​ в вашу программу:​ 
 +<code c> 
 +#include grpstick.h 
 +</​code>​ 
 +В этом случае порты джойстика будут опрашиваться автоматически и добавляться по ИЛИ к нажатиям клавиш на клавиатуре. Вы сможете пользоваться такими функциями,​ как ''​[[#​isspbar()]]'',​ ''​[[#​isleft()]]''​ и др. без изменения текста вашей программы. 
 + 
 +При этом, надо учитывать то, что мышь, опрашиваемая как джойстик,​ может давать постоянные срабатывания кнопок <​key>​→</​key>​ и <​key>​↓</​key>​. Для того, чтобы этого избежать можно использовать специальную функцию ''​[[#​chkmouse()]]''​ из ''​grpstick.h''​ которая сама определит по этим признакам подключена ли мышь к порту джойстика и, если она подключена,​ исключит этот порт из опроса как порт джойстика. 
 + 
 +Кроме этого, вы можете сами использовать системные переменные ''​_NoMous1''​ и ''​_NoMous2''​ для 1–го и 2–го портов соответственно,​ задавая им значения TRUE или FALSE в явном виде. В этом случае использование функции ''​[[#​chkmouse()]]''​ будет необязательным. 
 + 
 +По умолчанию ''​[[#​grpini()]]''​ устанавливает ''​_NoMous1=FALSE''​ и ''​_NoMous2=TRUE''​ т.е. считает,​ что к порту 1 подключена мышь, а к порту 2 джойстик. 
 +  
 +Если вы хотите чтобы работало автоопределение мыши для обоих портов с помощью функции ''​[[#​сhkmouse()]]'',​ то предварительно установите ''​_NoMous1=TRUE''​. 
 +  
 +Если вы хотите использовать только джойстик в порте 2 без автоопределения мыши и сократить размер кода, вы можете также написать ''#​define JOY2ONLY''​ перед ''#​include grpstick.h''​ 
 + 
 +{{anchor:​utilites}} 
 +====== GRPLIBM ====== 
 + 
 +Функции из библиотеки ''​GRPLIBM.CRL''​ предназначены для использования в программах,​ написанных для компилятора [[bds_c:​bds_c|BDS C]]. Они подключаются к программе на шаге редактирования ''​clink''​. При этом в параметре ''​-f''​ командной строки clink имя библиотеки ''​GRPLIBM''​ должно быть указано раньше имён библиотек ''​GRPLIB''​x ПС "​МАЭСТРО"​. 
 + 
 +Музыкальные отрывки на MML+ подготавливаются,​ транслируются и проверяются с помощью редактора [[msx:​maestro:​med:​med|MED]],​ а затем записываются на диск в виде готовых к исполнению музыкальных фрагментов в формате системной музыкальной очереди (СМО) MSX. 
 + 
 +Структура музыкального фрагмента:​ 
 +<​code>​ 
 +┌──────┬──────┬───────┬──────┬──────┬──────┬── ... ─┬──...────┬──...───┐ 
 +│VAlen │VAptr │ VBlen │VBptr │VClen │VCptr │ VAq    │  VBq    │ VCq    │ 
 +└──────┴──────┴───────┴──────┴──────┴──────┴── ... ─┴──... ───┴──...───┘ 
 +</​code>​ 
 + 
 +где: 
 +  * ''​VAq'',​ ''​VBq'',​ ''​VCq''​ — очереди пакетов для голосов A, B и С, подготовленные функцией mmq; 
 +  * ''​VAlen'',​ ''​VBlen'',​ ''​VClen''​ — их длины (включая завершающие 0хFF); 
 +  * ''​VAptr'',​ ''​VBptr'',​ ''​VCptr''​ — указатели начала цикла для каждого голоса. 
 + 
 +Эти фрагменты могут быть присоединены к программе заранее с помощью EDL (Extra Data Linker), входящего в ПС "​МАЭСТРО",​ либо загружаться динамически в процессе выполнения программы,​ например,​ функцией ''​[[#​swapin()]]''​. 
 + 
 +Программа должна быть составлена с учётом следующих требований:​ 
 +  * должны быть указаны ''#​include''​ для ''​grplib0.h''​ и ''​grpmus.h''​ 
 +  * в начале выполнения вызываются функции ''​[[#​grpini()]]'',​ ''​[[#​musini()]]''​ и, если используется LFO, ''​[[#​lforeset()]]''​ (в указанном порядке!) 
 +  * функция ''​[[#​tickexit()]]''​ должна содержать вызов функции ''​[[#​mutick()]]'',​ а если используется LFO — также и ''​[[#​lfotick()]]''​ 
 +  * должен быть включён механизм прерываний (''​[[#​TICKON]]''​) 
 + 
 +Когда эти условия выполнены,​ можно вызывать функцию ''​[[#​play()]]''​. Она сбрасывает предыдущее состояние PSG и СМО и "​запускает"​ исполнение указанного музыкального фрагмента однократно или в цикле. Все дальнейшие операции с музыкальной очередью производятся асинхронно. 
 + 
 +Функция ''​[[#​mutick()]]'',​ вызываемая в подпрограмме ''​[[#​tickexit()]]'',​ переносит максимально возможное число музыкальных пакетов из входной очереди в системную;​ если входная очередь исчерпана и нет признака цикла, заносит признак окончания очереди в СМО 
 +данного голоса. Интерпретация пакетов и непосредственное управление PSG осуществляется подпрограммой обработки СМО, входящей в состав обработчика прерываний BIOS MSX. 
 +Исключением являются пакеты управления LFO и шумом, которые интерпретируются функцией ''​[[#​mutick()]]''​ и в системную очередь не переписываются;​ поэтому,​ например,​ включения и выключения шума, заданные операторами (и), не синхронизированы с теми местами нотной записи,​ где стоят (и), а наступают раньше. В случае,​ если (и) стоят близко к началу записи,​ они оба могут быть обработаны ''​[[#​mutick()]]''​ при начальном заполнении системной 
 +очереди,​ до начала исполнения,​ и шум вообще не включится;​ однако при циклическом исполнении фрагмента при втором и последующих проходах включение и выключение шума будет происходить. 
 + 
 +С помощью функции ''​[[#​ismus()]]''​ можно определить состояние СМО для каждого из голосов;​ функция ''​[[#​musoff()]]''​ "​выключает"​ музыку и сбрасывает все очереди. 
 + 
 +Для случаев,​ когда музыкальные фрагменты не могут быть оттранслированы заранее,​ например,​ для разработки диалоговых музыкальных программ,​ в пакет MEDIA включён транслятор с MML+, оформленный в виде функции [[#mmq()]], который транслирует исходную строку на MML+ во внутренний формат СМО — последовательность музыкальных пакетов 
 + 
 +===== Функции управления музыкальной очередью ===== 
 + 
 +=== play() === 
 +<code с> 
 +play(cycle,​qad) 
 +char *qad; 
 +int cycle; 
 +</​code>​ 
 +Ставит музыкальный фрагмент с адресом ''​qad''​ в музыкальную очередь. 
 + 
 +Eсли cycle=0, элемент играется один раз; в противном случае ''​[[#​mutick()]]'',​ встретив байт 0xFF, не переписывает его в системную очередь,​ а начинает с места данной входной очереди,​ указанного в ''​Vptr''​. 
 + 
 +Если в нотной строке не было операторов ':',​ указатель содержит 0; если встретилось несколько операторов ':',​ указатель соответствует последнему из них. 
 + 
 +Вызывает ''​[[#​lf4init()]]'',​ включает шум. 
 + 
 +/* 
 +<code c> 
 +play(cycle,​qad) 
 +char *qad; 
 +int cycle; 
 +</​code>​ 
 +То же, что play(), исключая вызов ''​[[#​lfo4init()]]''​ 
 +*/ 
 +=== mutick() === 
 +<code с> 
 +mutick() 
 +</​code>​ 
 +Вызывается в [[#​tickexit()]] для периодической перезаписи музыкальных пакетов в системную музыкальную очередь и интерпретации пакетов управления LFO и шумом. 
 + 
 +=== musoff() === 
 +<code с> 
 +musoff() 
 +</​code>​ 
 +"​Выключает"​ музыку,​ сбрасывает системные очереди. 
 + 
 +=== musini() === 
 + 
 +<code c> 
 +musini(p) 
 +char *p;  
 +</​code>​ 
 +Инициализирует глобальные переменные;​ сбрасывает системные очереди. 
 + 
 +Если p=0, в качестве области параметров LFO берётся 80 байтов в рабочей области [[msx:​basic:​|]],​ начиная с адреса 0xF418, иначе эта область помещается по указанному адресу p. 
 + 
 +=== ismus() === 
 +<code c> 
 +char ismus()  
 +</​code>​ 
 +Возвращает байт, ​ разряды 0-2 которого соответствуют состоянию системных очередей голосов 1-3. 
 + 
 +Например,​ если ''​ismus()=0'',​ все три голоса молчат;​ если ''​ismus()=4'',​ играет только голос 3. 
 + 
 +=== xmus() === 
 + 
 +<code c> 
 +xmus() 
 +</​code>​ 
 +Приостанавливает музыку,​ "​замораживает"​ очереди. При повторном вызове продолжает исполнение с места остановки. 
 + 
 +=== autoplay() === 
 +<code c> 
 +autoplay(va,​vb,​vc)  
 +char *va,​*vb,​*vc;​ 
 +</​code>​ 
 +"​Шарманка";​ обеспечивает автоматическое (без подкачки по ''​[[#​mutick()]]''​) проигрывание музыкальных очередей va,vb,vc. Каждая из очередей при этом должна иметь длину 129 байтов или 1 байт (включая замыкающие 0xFF). Для подгонки длины можно вставлять фиктивные операторы m, разбивать ноты по длительности и т.п. 
 + 
 +=== int mmq() === 
 +<code c> 
 +int mmq(pa,​pq,​yy,​tm) 
 +char *pa,*p;  
 +unsigned *tm,*yy; 
 +</​code>​ 
 +Транслятор MML+; транслирует символическую строку ​ MML+, находящуюся по адресу ''​pa'',​ в последовательность музыкальных пакетов,​ оканчивающуюся 0хFF, и помещает её по адресу ''​pq''; ​ возвращает длину полученной очереди пакетов,​ а при ошибках трансляции — номер позиции в исходной строке,​ содержащей ошибку,​ со знаком минус; в слово по адресу ''​yy''​ заносит указатель цикла ''​Vptr'';​ в слово по адресу ''​tm''​ заносит суммарную продолжительность звучания в тиках.  
 + 
 +(Теоретически возможный случай продолжительности > 65536 тиков, т.е. > 18 мин. в расчёт не принимается ввиду его практической невероятности и бесполезности.) 
 + 
 +=== lftq() === 
 +<code c> 
 +int lftq(qn) ​   
 +char qn; 
 +</​code>​ 
 +Сообщает число свободных байтов в системной музыкальной очереди канала ''​qn''​. 
 + 
 +=== putq() === 
 +<code c> 
 +putq(qn,​byte) 
 +char qn,byte; 
 +</​code>​ 
 +Помещает byte в системную музыкальную очередь канала ''​qn''​. 
 + 
 +===== Функции для прямого управления PSG ===== 
 + 
 +=== setlfo() === 
 +<code c> 
 +int setlfo(v,​typ,​t,​a) 
 +int t,a; 
 +char v,typ; 
 +</​code>​ 
 +Заносит параметры LFO: тип (0-2), период и амплитуду (0-32767) для голосов 1-3 (v=0-2) или для шума (v=3) в блок управления LFO и инициализирует этот блок. ( Структура блока управления задана в ''​GRPMUS.H''​. Включение и выключение LFO для голоса или шума производится установкой в 1 или 0 глобальных переменных ''​[[#​_FMFL[i]]]''​). 
 + 
 +Если входные значения ошибочны,​ возвращает -1. 
 + 
 +=== lfinit() === 
 +<code c> 
 +lfinit(p) 
 +struct _LF *p; 
 +</​code>​ 
 +Инициализирует рабочие переменные LFO в указанном в p блоке управления LFO в соответствии с заданными ранее параметрами. 
 + 
 +=== lf4init() === 
 +<code c> 
 +lf4init() 
 +</​code>​ 
 +Выполняет ''​[[#​lfinit()]]''​ для всех четырёх блоков управления LFO. 
 + 
 +=== lfreset() === 
 +<code c> 
 +lfreset() 
 +</​code>​ 
 +Сбрасывает все параметры LFO, выключает LFO для всех голосов и шума. 
 + 
 +=== lfotick() === 
 +<code c> 
 +lfotick() 
 +</​code>​ 
 +Вызывается в ''​[[#​tickexit()]]'';​ управляет LFO, меняя частоту PSG. 
 + 
 +=== noisep() === 
 + 
 +<code c> 
 +noisep() 
 +</​code>​ 
 +Загружает период шума в PSG из глобальной переменной ''​[[#​_NP]]''​. (пять младших битов ''​_NP''​). 
 + 
 +=== noise() === 
 +<code c> 
 +noise() 
 +</​code>​ 
 +Включает шум в голосах,​ которым соответствуют '​0'​ в маске. 
 + 
 +Маска находится в трёх старших (левых) битах ''​_NP''​. 
 + 
 +=== noisev() === 
 +<code c> 
 +noisev(v,​on) 
 +char v,on; 
 +</​code>​ 
 +Включает (если on=1) или выключает (on=0) шум в голосе ''​v''​. 
 + 
 +=== xnoise() === 
 +<code c> 
 +xnoise(v) 
 +char v; 
 +</​code>​ 
 +Поочерёдно включает/​выключает шум в указанном голосе ''​v''​. 
 + 
 +=== notick() === 
 +<code c> 
 +notick() 
 +</​code>​ 
 +Вызывается в ''​[[#​tickexit()]]'';​ осуществляет модуляцию шума (linear noise oscillation,​ LNO): если установлен глобальный флаг _NMFL, "​базовый"​ период шума, заданный в noisep(), модулируется через ​ каждые NТ тиков случайным приращением в диапазоне (-NA,NA). 
 + 
 +Значения NT, NA и периода шума NP хранятся в глобальных переменных,​ определённых в ''​GRPMUS.H''​. Первоначально они устанавливаются в 0 функцией musini(). 
 + 
 +=== xlno() === 
 +<code c> 
 +xlno() 
 +</​code>​ 
 +Включает/​выключает модуляцию шума. 
 + 
 + 
 +===== Функции для поддержки 4-х цветов и мерцания в режиме TEXT2 для MSX2 ===== 
 + 
 + 
 +=== setblnk() === 
 +<code c> 
 +setblnk(txt,​bg,​on,​off) 
 +int txt,​bg,​on,​off;​ 
 +</​code>​ 
 +Задаёт параметры мерцания (все четыре параметра должны быть в диапазоне 0-15). ​  
 + 
 +''​txt''​ и ''​bg''​ задают альтернативную пару цветов текст/​фон. Мерцающие символы поочерёдно высвечиваются то основными,​ то альтернативными цветами. 
 + 
 +(Позиции экрана,​ в которых должно происходить мерцание,​ задаются установкой соответствующих битов в Color Table). 
 + 
 +Период мерцания задаётся величинами on - время высвечивания альтернативным цветом и off - основным (*1/6 сек.). 
 + 
 +Если оn и off равны 0, мерцания нет, все выводится в основных цветах. Если on=15, а off=0, мерцания также нет, но позиции,​ помеченные в Color Table, выводятся альтернативными цветами,​ т.е. появляется возможность работать в режиме TEXT2 с четырьмя цветами. 
 + 
 + 
 +=== rstblnk() === 
 +<code c> 
 +rstblnk() 
 +</​code>​ 
 +Устанавливает период мерцаний равным 0, т.е. выключает мерцание на всем экране,​ не изменяя Color Table. 
 + 
 +=== clrblnk() === 
 +<code c> 
 +clrblnk() 
 +</​code>​ 
 +Обнуляет Color Table, т.е выключает мерцание для каждой позиции экрана. 
 + 
 +=== blink() === 
 +<code c> 
 +blink(x,​y,​len) 
 +int x,y,len; 
 +</​code>​ 
 +Включает мерцание для ''​len''​ позиций экрана,​ начиная с позиции с координатами (''​x,​y''​). 
 + 
 +=== xblink() === 
 +<code c> 
 +xblink(x,​y,​len) 
 +int x,y,len; 
 +</​code>​ 
 +Переключает мерцание для ''​len''​ позиций экрана,​ начиная с позиции с координатами (''​x,​y''​) (т.е. включает для выключенных,​ выключает для включённых). 
 + 
 +=== dblink() === 
 +<code c> 
 +dblink(x,​y,​len) 
 +int x,y,len; 
 +</​code>​ 
 +Выключает мерцание для ''​len''​ позиций экрана,​ начиная с позиции с координатами (''​x,​y''​). 
 + 
 +===== Ограничения ===== 
 + 
 +Ограничения,​ накладываемые звукогенератором и механизмом прерываний:​ 
 +  - Длительность звучания ноты измеряется в тиках — 1/60 сек. (на некоторых машинах — 1/​50). ​ Она определяется по формуле:​ \\ d=14400/​(t*l) ​     (на 50–гц машинах — 12000), минимальная длительность равна двум тикам, максимальная - 4095. \\ Систематическая погрешность округления при нецелом частном может приводить к рассинхронизации голосов,​ которую приходится устранять вручную,​ вставляя дополнительные ​ ноты и контролируя длительности ​ голосов в поле "​Ticks"​ на [[msx:​maestro:​med:​med|экране музыкального редактора]]. 
 +  - В моменты обращения к диску системный обработчик прерываний получает управление с задержкой, ​ что ​ приводит ​ к  искажению длительностей нот, загруженных в это время в звукогенератор. 
 +  - Если ''​[[#​tickexit()]]''​ в программе пользователя ​ слишком ​ долго не получает управления (например,​ при неправильно организованном ожидании ввода с клавиатуры;​ при использовании отладочной функции ''​[[#​dump()]]''​ с большим объёмом выдачи и т.п.), и успевают доиграть все  
 +пакеты,​ поставленные mutick() в системную очередь,​ может произойти отключение или рассинхронизация голосов. Поэтому надо ​ внимательно отслеживать возможные источники задержек,​ обязательно вставлять ''​[[#​totick()]]''​ в продолжительные или зависящие от внешних событий циклы и функции,​ осторожно пользоваться ''​[[#​DIS_INTERRUPT]]'',​ ''​[[#​TICKOFF]]''​ и ''​[[#​TICKSTOP]]''​. 
 +Если специфика программы такова,​ что гарантировать регулярное выполнение tickexit() невозможно,​ остаётся воспользоваться функцией ''​[[#​autoplay()]]''​. 
 +   
 +__//​Примечание//​__:​  
 +  * ''​[[#​grpini()]]'',​ ''​[[#​tickexit()]]'',​ ''​[[#​totick()]]'',​ ''​[[#​dump()]]'',​ ''​[[#​DIS_INTERRUPT]]'',​ ''​[[#​TICKOFF]]'',​ ''​[[#​TICKSTOP]]''​ — функции,​ входящие в ПС "​МАЭСТРО"​.  
 +  * ''​[[#​swapin()]]''​ — функция BDS C. 
 + 
 + 
 +====== Утилиты ====== 
 + 
 +В данном документе содержится описание применения утилит,​ входящих в ПС «МАЭСТРО». Документ предназначен для разработчиков программного обеспечения на компьютерах ​ MSX2  и  MSX  и содержит следующие разделы:​ 
 + 
 +  * Назначение утилит 
 +  * Условия применения 
 +  * Порядок работы с утилитами,​ форматы данных и особенности использования 
 + 
 +{{anchor:​utilites_n1}} 
 +===== Назначение утилит ===== 
 + 
 +|[[#​BLADE.COM]]|Bload Address Extractor|извлечение адресов из файлов BLOAD/​BSAVE| 
 +|[[#​CDEX.COM]]|C Documentation Extractor|извлечение документации из автодокументированых программ Си| 
 +|[[#​DS.COM]]|Directory Sorter|вывод оглавления диска на экран в отсортированом виде| 
 +|[[#​DT.COM]]|Disk to Tape|перезапись файлов с диска на магнитную ленту| 
 +|[[#​DUMP.COM]]|Dump|дамп/​объединение различных источников информации| 
 +|[[#​DURATION.COM]]|Duration|подсчет длительности интервалов времени| 
 +|[[#​EDL.COM]]|Extra Data Linker|прикомпоновка данных к COM-файлам,​ созданным при помощи BDS C| 
 +|[[#​FCX.COM]]|Files Compressor/​Expander|компрессор/​экспандер для сжатия/​расширения файлов| 
 +|[[#​FICO.COM]]|Files Collector|диалоговый сборщик нескольких файлов в один файл| 
 +|[[#​HC.COM]]|Hardcopy|вывод файлов на принтер| 
 +|[[#​SS.COM]]|Sector Server|копирование/​проверка дисков по секторам| 
 +|[[#​TD.COM]]|Tape to Disk|перезапись файлов с магнитной ленты на диск| 
 +|[[#​PICO.COM]]|Picture Compressor| | 
 + 
 +Все утилиты написаны на языке С (компилятор BDS C) и ассемблер (GEN80) с использованием «Графической Библиотеки MSX для BDS C». 
 + 
 + 
 +{{anchor:​utilites_n2}} 
 +===== Условия применения утилит ===== 
 + 
 +Для работы утилит требуется MSX компьютер с 64 кбайт оперативной памяти и как минимум одним дисководом. Большинство утилит может выполняться как на [[msx:​msx_1|MSX]] так и на [[msx:​msx_2|MSX2]]. Случаи использования [[msx:​msx_2|MSX2]] оговариваются особо. Операционная система:​ [[msx:​dos:​|]] версии 1.03 (''​COMMAND.COM''​ 1.11). 
 + 
 +Внимание! Для нестандартных модификаций операционной системы и консольного процессора нормальная работа утилит не гарантируется. 
 + 
 +{{anchor:​utilites_n3}} 
 +===== Порядок работы с утилитами,​ форматы данных и особенности использования ===== 
 + 
 +Порядок работы с утилитами,​ форматы данных и особенности использования. Ниже приводятся описания параметров командных строк и функций утилит ПС «МАЭСТРО». 
 + 
 +__//​Примечание.//​__ 
 +\\ Большинство утилит,​ не ведущих диалог,​ выводит краткое описание своих командных строк при вызове их без параметров. 
 + 
 +Формат записи параметров:​ 
 +  * В квадратных скобках «[» и «]» записываются необязательные параметры,​  
 +  * в фигурных «{» и «}» — альтернативные значения параметров,​  
 +  * в угловых «<» и «>» — смысловые значения параметров. 
 + 
 +  * Вертикальная черта «|» служит для разделения альтернатив («или»),​ 
 +  * многоточие «…» — для указания на группу однотипных параметров. 
 + 
 +==== BLADE.COM ==== 
 + 
 +|<100% 25% 75%>| 
 +^Полное название|Bload Address Extractor| 
 +^Назначение|Извлечение адресов из файлов ''​BLOAD''/''​BSAVE''​| 
 +^Формат командной строки|<​code>​blade [<​fileset>​]</​code>​| 
 +^Параметры|<​WRAP>​ 
 +  * ''<​fileset>''​ — любая стандартная маска набора файлов [[msx:​dos:​|]] с расширением «!» — [and] not. Если не указан — ''​*.*''​ 
 +</​WRAP>​| 
 +^Особенности|Файлы,​ релевантные маске, сортируются по алфавиту и проверяются на наличие FE в первом байте файла. В случае присутствия FE на экран выводится имя файла и три шестнадцатеричных слова: адрес загрузки,​ адрес конца и адрес передачи управления.| 
 +^Примеры|<​code>​A>​blade</​code>​ <​code>​A>​blade *.gm?</​code>​| 
 + 
 +==== CDEX.COM ==== 
 + 
 +|<100% 25% 75%>| 
 +^Полное название|C Documentation Extractor| 
 +^Назначение|Извлечение документации из самодокументированных программ на Си.| 
 +^Формат командной строки|<​code>​cdex <​source1>​[.c] … <​sourceN>​[.c] [=<​document>​[.doc]]</​code>​| 
 +^Параметры|<​WRAP>​ 
 +  * ''<​source1>​ …N>​[.c]''​ ... ''<​sourceN>​[.c]''​ — имена файлов с необязательным суффиксом ''​.C''​ в которых находятся исходные тексты программ на языке Си. 
 +  * ''​[<​document>​[.doc]]''​ — имя файла, в который будет выводиться документация. Если не указан — ''<​source>​.doc''​ 
 +</​WRAP>​| 
 +^Особенности|В файл документации выводятся все строки программы,​ находящиеся на нулевом уровне вложенности фигурных скобок:​ глобальные переменные,​ имена функций и описания их параметров. На этом же уровне вложенности рекомендуется писать комментарии,​ описывающие назначение функций и параметров.| 
 +^Примеры|<​code>​A>​cdex myprog</​code>​ <​code>​A>​cdex myprog1 myprog2 =myprog.cdx</​code>​| 
 + 
 + 
 + 
 +==== DS.COM ==== 
 + 
 +|<100% 25% 75%>| 
 +^Полное название|Directory Sorter| 
 +^Назначение|Вывод оглавления диска на экран в отсортированном виде.| 
 +^Формат командной строки|<​code>​ds[/​p] <​fileset></​code>​| 
 +^Параметры|<​WRAP>​ 
 +  * ''/​p''​ — вывод копии экрана на принтер. 
 +  * ''<​fileset>''​ — любая стандартная маска набора файлов [[msx:​dos:​|]] с расширением «!» — [and] not. Если не указан — *.* 
 +</​WRAP>​| 
 +^Особенности|Файлы,​ релевантные маске, выводятся на экран в отсортированном по алфавиту суффиксов,​ а внутри них — по именам файлов виде.| 
 +^Примеры|<​code>​A>​ds</​code>​ <​code>​A>​ds b:</​code>​ <​code>​A>​ds *.c</​code>​| 
 + 
 +==== DT.COM ==== 
 + 
 +|<100% 25% 75%>| 
 +^Полное название|Disk to Tape| 
 +^Назначение|Перезапись файлов с диска на магнитную ленту| 
 +^Формат командной строки|<​code>​dt <​diskfile>​ <​tapefile>​ {A|B|C|U} {len|*} [{H|L}] [B]</​code>​| 
 +^Параметры|<​WRAP>​ 
 +  * ''​diskfile''​ — имя файла на диске 
 +  * ''​tapefile''​ — имя файла на ленте (6 символов или * для формата UNDEF) 
 +  * ''​{A|B|C|U}''​ — формат выводного файла на ленте:​ 
 +    * ''​А''​ — ASCII, 
 +    * ''​B''​ — BSave, 
 +    * ''​C''​ — CSave, 
 +    * ''​U''​ — UNDEF (неопределенный — без заголовка). 
 +  * ''​{len|*}''​ длина файла в байтах:​ 
 +    * ''​len''​ — в виде числа в явном виде, 
 +    * ''​*''​ — исходя из размера дискового файла или из длины, вычисленной из заголовка дискового файла для BSave. 
 +  * ''​[{H|L}]''​ — плотность записи на ленте (необязательный параметр):​ 
 +    * ''​H''​ — высокая,​ 
 +    * ''​L''​ — низкая. 
 +  * ''​[B]''​ — Batch (необязательный параметр):​ не ожидать нажатия на клавишу <​key>​SHIFT</​key>​ после запуска мотора магнитофона для начала записи информации. 
 +</​WRAP>​| 
 +^Особенности|<​WRAP>​ 
 +  - За одно выполнение утилиты можно записать на ленту файл размером не более 32 кбайт. 
 +  - <​key>​CTRL + STOP</​key>​ прерывает выполнение утилиты. 
 +  - Вместо однобуквенных сокращений параметров можно записывать их полное наименование (см. пример). 
 +</​WRAP>​| 
 +^Примеры|<​code>​A>​dt pacman.gm PACMAN bload * high batch</​code>​ <​code>​A>​dt pacman.gm PACMAN b * l b</​code>​| 
 + 
 +==== DUMP.COM ==== 
 + 
 +|<100% 25% 75%>| 
 +^Полное название|Super Dump| 
 +^Назначение|Дамп/​объединение различных источников информации.| 
 +^Форматы вызова|<​WRAP>​ 
 +  * для дампа файла: <​code>​dump file [B[#]n] [S[#]n] [L[#]n] [H] [D] [P] [X[#]n] [{=|%|$|-}outfile]</​code>​ 
 +  * для сектора на диске: <​code>​dump (n) [B[#]n] [S[#]n] [L[#]n] [H] [D] [P] [X[#]n] [{=|%|$|-}outfile]</​code>​ 
 +  * для памяти:​ <​code>​dump #n[/p[s]] [M[#]m] [L[#]n] [D] [P] [X[#]n] [{=|%|$|-}outfile]</​code>​ 
 +  * для видопамяти:​ <​code>​dump #{0|1}.n [L[#]n] [R] [D] [P] [X[#]n] [{=|%|$|-}outfile]</​code>​ 
 +</​WRAP>​| 
 +^Параметры|<​WRAP>​ 
 +  * ''​n''​ — десятичное целое число в диапазоне 0…65535;​ 
 +  * ''#​n''​ — шестнадцатеричное число в диапазоне 0…0xFFFF;​ 
 +  * ''​B''​ — BASE: базовое (начальное) значение счетчика адреса от начала дампа (в том числе, от начала SKIP); 
 +  * ''​S''​ — SKIP: пропуск [#]n байтов после BASE; 
 +  * ''​L''​ — LENGTH: длина данных (после SKIP, 0xFFFF по умолчанию);​ 
 +  * ''​H''​ — HEADER: отделить 7 байт заголовка BLoad при выводе на экран;​ 
 +  * ''​D''​ — DISASSEMBLY (пока не реализован);​ 
 +  * ''​P''​ — PRINTER: вывод дампа на принтер;​ 
 +  * ''​X[#​]n''​ — XOR: подвергать операции xor каждый выводимый байт с числом n (0…255) или #n (0...0xFF);​ 
 +  * ''​=|%|$|-''​ — префикс и тип выводного файла outfile: 
 +    * ''​=''​ ASCII — шестнадцатеричный и символьный,​ 
 +    * ''​%''​ ASCII — восьмеричный,​ 
 +    * ''​$''​ BINARY — двоичная копия источника дампа,​ 
 +    * ''​-''​ BINARY — двоичная копия источника дампа без вывода на экран;​ 
 +    * ''/​p[s]''​ — первичный и вторичный слоты;​ 
 +    * ''​M''​ — MEMORY MAPPER: страница m (0…255) или #m (0…0xFF);​ 
 +    * ''​0|1''​ — нижние (0) или верхние (1) 64 кбайт видеопамяти;​ 
 +    * ''​R''​ — использовать регистры V9938 вместо вызова B[[msx:​bios|BIOS]] / [[msx:​bios#​subrom|SubROM]] (для MSX1 с V9938 и 128 кбайт VRAM). 
 +</​WRAP>​| 
 +^Особенности|<​WRAP>​ 
 +  - Нажатие любой клавиши останавливает/​продолжает дамп. Нажатие клавиши <​key>​STOP</​key>​ приводит к выходу в [[msx:​dos:​|]]. 
 +  - При помощи утилиты DUMP можно объединить несколько разных фрагментов разных источников в один файл — разделителем источников в командной строке является символ '&'​ (см. пример). 
 +  - В качестве отдельных источников в командной строке могут использоваться специальные параметры (без пробелов) 
 +    - '':​hh…hh''​ — для записи байтов в шестнадцатеричном виде 
 +    - ''>​a…z''​ — для записи байтов в символическом виде  
 + - Если в качестве источника (источников) используется файл CON (консоль) — утилита запрашивает на консоли,​ в каком виде предполагается осуществлять ввод — шестнадцатеричном или ​   символическом. При этом в режиме шестнадцатеричного ввода все не шестнадцатеричные символы игнорируются. 
 +</​WRAP>​| 
 +^Примеры|<​WRAP>​ 
 +  - Вывести на консоль первые 100 байт файла ''​foo.dat''​ <​code>​A>​dump foo.dat l100</​code>​ 
 +  - Объединить в выводной файл ''​outdat.gro'':​ нижние 256 байт RAM начиная с адреса 0, 110 байт файла frotz.dat (предварительно пропустив 512 байт), сектор 0. <​code>​A>​dump #0 l#100 & frotz.dat s512 l110 & (0) -outdat.gro</​code>​ 
 +</​WRAP>​| 
 + 
 +==== DURATION.COM ==== 
 + 
 +|<100% 25% 75%>| 
 +^Полное название|Duration| 
 +^Назначение|Подсчет длительности интервалов времени.| 
 +^Формат командной строки|<​code>​duration [{z|Z}]</​code>​| 
 +^Параметры|<​WRAP>​ 
 +  * ''​z''​ — запомнить текущее время в локальный счетчик,​ 
 +  * ''​Z''​ — запомнить текущее время в локальный и глобальный счетчики. 
 +</​WRAP>​| 
 +^Особенности|<​WRAP>​ 
 +  - Для правильной работы утилиты необходим компьютер MSX2. 
 +  - Если утилита вызывается без параметров — она выводит на консоль разницу между текущим значением времени и значениями,​ записанными в локальный и глобальный счетчики времени. 
 +  - Если локальный или глобальный счетчики равны нулю — они автоматически устанавливаются на текущее время. 
 +  - ''​cc.com''​ v1.50aR при каждом выполнении автоматически записывает в счетчик локального времени текущее время. 
 +</​WRAP>​| 
 +^Примеры|<​WRAP>​ 
 +  - Подсчет времени компиляции файла ''​gro.c''​ <​code>​ 
 +A>cc gro 
 +A>​duration 
 +</​code>​ 
 +  - Подсчет времени компоновки файла ''​gro.crl''​ <​code>​ 
 +A>​duration z 
 +A>clink gro -f grplib4 grplib3 grplib2 grplib1 grpliba -s -e4000 
 +A>​duration 
 +</​code>​ 
 +</​WRAP>​| 
 + 
 +==== EDL.COM ==== 
 + 
 +|<100% 25% 75%>| 
 +^Полное название|Extra Data Linker| 
 +^Назначение|Прикомпоновка данных к файлам COM, порождённым при помощи BDS C для последующего использования этих данных при помощи библиотечных функций ''​geteda()''​ и ''​geteda2()''​.| 
 +^Формат командной строки|<​code>​edl <​COM_file>​ <​new_COM_file>​ [-c <​files>​] [-e <​files>​] [-f <​files>​]</​code>​| 
 +^Параметры|<​WRAP>​ 
 +  * ''​COM_file''​ — файл, порождённый clink (записывается без суффикса .COM) 
 +  * ''​new_COM_file''​ — новый файл COM с прикомпоноваными к нему данными (записывается без суффикса .COM) 
 +  * ''​-c''​ — прикомпоновывать данные после конца кода, 
 +  * ''​-e''​ — прикомпоновывать данные в начале области External 
 +  * ''​-f''​ — прикомпоновывать данные после конца области External (free RAM) 
 +  * ''<​files>''​ — файлы данных,​ записанные через пробел:​ ''​-c file1 file2 file3''​ 
 +</​WRAP>​| 
 +^Особенности|<​WRAP>​ 
 +  - Если используется более одного ключа одновременно — порядок их следования должен быть возрастающим (по адресам прикомпоновки):​ \\ ''​-c … -e … -f …''​ 
 +  - Префиксы дисковых приводов не попадают в оглавления имён прикомпонованых данных,​ а суффиксы (.расширения) — являются неотъемлемой частью каждой точки входа в оглавление. 
 +</​WRAP>​| 
 +^Примеры|<​code>​A>​edl mygame newgame -c game.mnt b:game.dat -f game.lib game.spr</​code>​ В результате выполнения данной строки будет создан новый файл NEWGAME.COM,​ состоящий из файла MYGAME.COM с прикомпоноваными к нему после конца кодов (и до начала области External) файлами GAME.MNT и GAME.DAT (последний считывается с диска B:) и после конца области External файлами GAME.LIB и GAME.SPR. Это типичный пример использования EDL для создания окончательного файла игровой программы.| 
 + 
 +==== FCX.COM ==== 
 + 
 +|<100% 25% 75%>| 
 +^Полное название|Files Compressor/​Expander| 
 +^Назначение|Компрессор/​экспандер для сжатия/​расширения файлов. \\ Компрессированые файлы могут быть экспандированы в программе пользователя при помощи библиотечной функции ''​expand()''​.| 
 +^Формат командной строки|<​code>​fcx <​infile>​ <​outfile>​ -{c|x}</​code>​| 
 +^Параметры|<​WRAP>​ 
 +  * ''<​infile>''​ — исходный файл 
 +  * ''<​outfile>''​ — результирующий файл 
 +  * ''​-c''​ — режим компрессии (Compress) 
 +  * ''​-x''​ — режим экспандирования (eXpand) 
 +</​WRAP>​| 
 +^Особенности|<​WRAP>​ 
 +  - Компрессирование основано на сжатии «однородностей» с элементом компрессии длиной 1 байт (алгоритм неадаптивный). Поэтому,​ файлы имеющие очень небольшое количество одинаковых подряд идущих байтов могут компрессироваться неэффективно и иногда даже возрастать в объеме (попробуйте компрессировать уже компрессированый файл). 
 +  - Для предварительной оценки степени компрессии без создания результирующего файла на диске, удобно использовать системный файл NUL в качестве ''<​outfile>''​. 
 +</​WRAP>​| 
 +^Примеры|<​code>​A>​fcx game.mnt nul -c</​code>​ <​code>​A>​fcx game.mnt gamec.mnt -c</​code>​| 
 + 
 + 
 +==== FICO.COM ==== 
 + 
 +|<100% 25% 75%>| 
 +^Полное название|Files Collector| 
 +^Назначение|Диалоговый сборщик нескольких файлов в один файл.| 
 +^Формат командной строки|<​code>​fico <​outfile></​code>​| 
 +^Параметры|<​WRAP>​ 
 +  * ''<​outfile>''​ — результирующий файл на диске 
 +</​WRAP>​| 
 +^Особенности|<​WRAP>​ 
 +  - Files Collector ведет диалог с пользователем,​ запрашивая последовательно:​ 
 +    * нужен ли 7-байтовый заголовок FE (в формате BLOAD/​BSAVE) для результирующего файла;​ 
 +    * имена считываемых файлов с количеством байт, которое необходимо пропустить перед копированием и количеством байт, которое после этого необходимо копировать в результирующий файл. 
 +  - Цифровые значения могут задаваться в десятичном или шестнадцатеричном виде — в последнем случае первым символом числа должен быть символ "#"​. 
 +  - CR (возврат каретки) предполагает ответ по умолчанию (обычно 0). 
 +</​WRAP>​| 
 +^Примеры|<​code>​A>​fico resfile.dat</​code>​| 
 + 
 + 
 +==== HC.COM ==== 
 + 
 +|<100% 25% 75%>| 
 +^Полное название|Hardcopy| 
 +^Назначение|Вывод файлов на принтер.| 
 +^Формат командной строки|<​code>​hc [<​options>​] [file] [<​options>​] [file2] … </​code>​| 
 +^Параметры|<​WRAP>​ Необязательные параметры (options), относящиеся к управлению печатью каждого файла, записываются перед именами соответствующих файлов и имеют в качестве первого символа слэш «/». 
 +\\ Параметры,​ относящиеся к управлению принтером [[msx:​star_gemini-10xr:​star_gemini-10xr|Star]]:​ 
 +  * ''/​N''​ — NORMAL — нормальная ширина букв; 
 +  * ''/​P''​ — PROPORTIONAL — пропорциональная ширина букв (то же самое, что NORMAL, но для точечной графики);​ 
 +  * ''/​E''​ — ELITE — средняя ширина букв; 
 +  * ''/​C''​ — CONDENSED — сжатая ширина букв; 
 +  * ''/​X''​ — EXPANDED — удвоенная ширина букв для /N, /P, /E, /C; 
 +  * ''/​S''​ — SMALL — уменьшенная высота букв (используются верхние индексы);​ 
 +  * ''/​IT''​ — ITALIC — курсив (наклон вправо);​ 
 +  * ''/​H''​ — ENHANCED — сдвиг на пол-точки с двойной печатью;​ 
 +  * ''/​D''​ — DOUBLE strike — двойной удар; 
 +  * ''/​Wnnn''​ — WIDTH — ширина строки nnn символов;​ 
 +  * ''/​V+''​ — VERTICAL step — подача бумаги для новой строки на ⅙ дюйма;​ 
 +  * ''/​V-''​ — VERTICAL step — подача бумаги для новой строки на ⅛ дюйма;​ 
 +  * ''/​Vnn''​ — VERTICAL step — подача бумаги для новой строки на nn/144 дюйма;​ 
 +  * ''/​Fnnn''​ — FORMAT tape — длина страницы для подачи бумаги (Form Feed) nnn строк — по умолчанию 2 строки;​ 
 +  * ''/​ESC..''​. — вывести код ESC и символы,​ следующие за ним — этот параметр должен быть последним в списке (если используется). 
 +Другие параметры:​ 
 +  * ''/​I+''​ — выводить информационную строку с названием файла, датой и временем печати (/I+ установлен по умолчанию);​ 
 +  * ''/​I-''​ — не выводить информационную строку;​ 
 +  * ''/​L+''​ — используются отдельные листы бумаги — отключение детектора конца бумаги и небольшое сокращение длины каждой страницы;​ 
 +  * ''/​L-''​ — отключить механизм нумерации страниц — может быть использован совместно с ''/​L+'';​ 
 +  * ''/​Lnnn''​ nnn — количество строк на каждой странице (обычно автоматически вычисляется исходя из размера шрифта и вертикальной подачи бумаги) — может быть использован совместно с ''/​L+''​ и ''/​L-'';​ 
 +  * ''/​$nnn''​ — задать начальный номер страницы nnn; 
 +  * ''/#​nnn''​ — печатать,​ начиная со страницы nnn (пропустить nnn-1 страниц),​ по умолчанию 1. 
 +</​WRAP>​| 
 +^Особенности|<​WRAP>​ 
 +  - Каждый файл печатается с параметрами,​ которые встретились ДО ЕГО ОПРЕДЕЛЕНИЯ — последний параметр из группы альтернативных (например,​ выбора шрифта) имеет больший приоритет. 
 +  - Если имя файла отсутствует — принтер будет настроен на тип печати при помощи управляющих кодов. 
 +  - Если вместо имени файла написана звездочка ''​*''​ — на принтер выводится копия текущего экрана. 
 +  - Для всех файлов,​ встретившихся в командной строке без указания параметра ''/​$nnn''​ сохраняется единая нумерация страниц. 
 +  - По концу каждой страницы предусмотрено ожидание нажатия пользователем клавиши после проверки/​коррекции установки бумаги. 
 +</​WRAP>​| 
 +^Примеры|<​code>​A>​hc/​c/​i- grpmsx1.h</​code>​ <​code>​A>​hc/​c/​s *</​code>​| 
 + 
 + 
 +==== SS.COM ==== 
 + 
 +|<100% 25% 75%>| 
 +^Полное название|Sector Server| 
 +^Назначение|Копирование/​проверка дисков по секторам.| 
 +^Формат командной строки|<​code>​ss {d1|*} d2 [d1s d1e d2s] [-p] [-b] [-v]</​code>​| 
 +^Параметры|<​WRAP>​ 
 +  * ''​d1''​ — имя дискового привода источника (откуда считывать);​ 
 +  * ''​*''​ — в качестве источника используются специальные кодовые последовательности,​ генерируемые утилитой Sector Server для проверки качества записи на диск. 
 +  * ''​d2''​ — имя дискового привода приемника (куда записывать);​ 
 +  * ''​d1s''​ — Disk 1 Start — начальный сектор источника;​ 
 +  * ''​d1e''​ — Disk 1 End — последний сектор источника;​ 
 +  * ''​d2s''​ — Disk 2 Start — начальный сектор приемника;​ 
 +  * ''​-p''​ — Pause — пауза перед начальным опросом дисковых приводов для установки требуемых дисков;​ 
 +  * ''​-b''​ — Batch — отмена запроса на подтверждение копирования для работы в потоке заданий;​ 
 +  * ''​-v''​ ''​- Verify''​ — считывание и проверка каждого сектора после записи (собственными средствами утилиты Sector Server). 
 +</​WRAP>​| 
 +^Особенности|<​WRAP>​ 
 +  - Имена дисковых приводов источника и приемника могут записываться без двоеточия.  
 +  - Если при копировании диска на диск не указывается диапазон копируемых секторов — копируются все секторы,​ включая резервные.  
 +  - Если в качестве источника используется ''​*''​ — информация на диске-приёмнике в указанном диапазоне секторов будет разрушена тестовыми последовательностями проверки качества поверхности диска. Если таким образом проверяются секторы 0…13 — после проверки диск необходимо форматировать. 
 +</​WRAP>​| 
 +^Примеры|<​WRAP>​ 
 +  - Копировать с А: на А: секторы 1…13 в секторы 1427…1439:<​code>​A>​ss a a 1 13 1427</​code>​ 
 +  - Копировать А: на B: с паузой и проверкой:​ <​code>​A>​ss a b -p -v</​code>​ 
 +  - Проверка качества поверхности всего диска на B: <​code>​A>​ss * b 0 1439</​code>​ 
 +</​WRAP>​| 
 + 
 +==== TD.COM ==== 
 + 
 +|<100% 25% 75%>| 
 +^Полное название|Tape to Disk| 
 +^Назначение|Перезапись файлов с магнитной ленты на диск.| 
 +^Формат командной строки|<​code>​td [<​protocol_file>​]</​code>​| 
 +^Параметры|<​WRAP>​ 
 +  * ''<​protocol_file>''​ — дисковый файл, в который выводится протокол работы пользователя с утилитой для последующего анализа введенных файлов,​ а также для подготовки заданий для утилиты [[#​DT.COM]] 
 +</​WRAP>​| 
 +^Особенности|Утилита ведет диалог с пользователем,​ выводя на экран меню управляющих клавиш и назначенных им функций. \\ При работе с утилитой допускается,​ что пользователь не знает, в каком формате (в каких форматах) записаны файлы на магнитной ленте и, поэтому,​ ему предоставляется возможность перед непосредственной записью на диск произвести предварительный анализ файла (файлов) на типы заголовков и данных. Все операции по анализу файлов на ленте могут записываться в файл протокола и/или выводиться на принтер. \\ Пользователю предоставляется также возможность вписывать в файл протокола произвольные комментарии во время анализа магнитной ленты. Основными форматы данных,​ «понимаемыми» утилитой являются ASCII, CLOAD, BLOAD и UNDEF для машин MSX.| 
 +^Примеры|<​code>​A>​td tape1.pro</​code>​| 
 + 
 +==== PICO.COM ==== 
 +FIXME 
 +|<100% 25% 75%>| 
 +^Полное название|Picture Compressor| 
 +^Назначение|Компрессия изображений| 
 +^Формат командной строки|<​code>​pico</​code>​| 
 +^Параметры| | 
 +^Особенности| | 
 +^Примеры| | 
 + 
 +==== SETPALET.COM ==== 
 + 
 +//​только для MSX2// 
 + 
 +Set Palette v1.02 
 + 
 +|<100% 25% 75%>| 
 +^Полное название|Set Palette| 
 +^Назначение| | 
 +^Формат командной строки|<​code>​setpalet [#fbB] [pRGB ... pRGB] [M]</​code>​| 
 +^Параметры|<​WRAP>​ 
 +  * ''#​fbB''​ — цвета стандартной палитры:​ 
 +    * ''​f''​ — изображения (0…F) 
 +    * ''​b''​ — фона (0…F) 
 +    * ''​B''​ — бордюра (0…F) 
 +  * pRGB — значения для палитры:​ 
 +    * ''​p''​ — номер палитры (0…F) 
 +    * ''​R''​ — красный (0…7) 
 +    * ''​G''​ — зелёный (0…7) 
 +    * ''​B''​ — синий (0…7) 
 +  * ''​M''​ — режим ручной установки палитры используя клавиши управления курсором,​ выход по <​key>'​Ввод '​⏎</​key>:​ <​code>​ 
 +   fgr bgr Bdr 
 +   ​15 ​  ​4 ​  5 ├── текущие значения 
 +   RGB RGB RGB 
 +   --- --- --- 
 +  └─────┬─────┘ 
 +        └─ задаваемые значения 
 +</​code>​ 
 +</​WRAP>​| 
 +^Особенности|Значения по умолчанию:​ <​code>#​F45 F777 4004 5007</​code>​| 
 +^Примеры|<​code>​A>​ setpalet #F45 F777 4004 5007</​code>​ <​code>​A>​ setpalet M</​code>​| 
 + 
 +{{anchor:​pac}} 
 +====== Pattern Composer ====== 
 +FIXME 
 +<​hidden>​ 
 + 
 +<​code>​ 
 + 
 +[[msx:​maestro:​pac:​|]] 
 + 
 + 
 +Компоновщик/​Редактор Знакоместной Графики версия 3.04 (C) А.Родионов 
 +---- 
 +      ​Pattern Composer ​ v3.04 
 + 
 +===== АННОТАЦИЯ ===== 
 + 
 +  В данном документе содержится описание применения программы «Pattern Composer» версии 2.02. Документ предназначен для разработчиков программного обеспечения на компьютерах MSX2 и MSX и содержит следующие разделы:​ 
 +  * Назначение,​ 
 +  * Условия применения,​ 
 +  * Порядок работ,​ 
 +  * Форматы данных,​ 
 +  * Рекомендации по использованию. 
 + 
 +«Pattern Composer» является авторской разработкой А. Б. Родионова (Москва,​ 1987–2022). Оригинальная документация ведется на английском языке для совместимости с компьютерами и другим оборудованием,​ не имеющим кириллических знакогенераторов и может быть поставлена по специальному заказу. По этой же причине англоязычными являются все комментарии и диалог,​ ведущийся программой,​ а также другими компонентами ПС «МАЭСТРО». 
 + 
 +Данный документ не следует рассматривать как учебное пособие по компьютерам MSX2 и MSX — напротив,​ он рассчитан на подготовленых программистов,​ знающих архитектуру этих компьютеров,​ но испытывающих затруднения в выборе инструментальных средств для разработки своих программ. 
 + 
 +1. НАЗНАЧЕНИЕ 
 + 
 +Программа Pattern Composer (Компоновщик Знакоместной графики) предназначена для разработки знакоместной графики в Screen 2. В качестве инструментальной машины используется ​ MSX2 (дополнительная память и мышь), но результирующие файлы полностью совместимы с MSX1. 
 + 
 +Программа использует в работе графические меню, выбор из которых осуществляется при помощи манипулятора мышь. 
 + 
 +Основным режимом работы программы является режим компоновки знакомест на полиэкране ​ из знакоместной библиотеки,​ которая может быть создана с помощью этой же программы,​ или может быть получена загрузкой файла, содержащего копию VRAM для Screen 2. Такой файл может быть подготовлен при помощи других графических редакторов или даже программы,​ написанной на языке Бейсик. 
 + 
 +Pattern Composer позволяет разрабатывать различные фазы движущихся объектов,​ редактировать их, получать копии изображений на бумаге,​ сохранять их в файлах в различных форматах,​ манипулировать с библиотеками знакомест,​ экранов и др. Форматы хранения данных совместимы с форматами,​ используемыми «Библиотекой функций MSX для BDS C» (далее просто «Библиотека функций»). 
 + 
 +Полиэкран может иметь различные конфигурации в зависимости от требований пользователя. 
 + 
 +Имеется встроенная функция «Help» с подразделами описаний форматов файлов,​ используемой терминологии и др. 
 + 
 +2. УСЛОВИЯ ПРИМЕНЕНИЯ 
 + 
 +Для работы программы Pattern Composer (в дальнейшем именуемой PAC) необходим компьютер MSX2, оснащённый манипулятором мышь (в дальнейшем просто мышь). Основное назначение РАС — подготовка графики для программ,​ которые работают в Screen 2 и Screen 4 (для V9938 Graphics 2 и Graphics 3). Компьютер MSX2 используется в качестве инструментальной машины из-за расширеных требований к человеко-машинному интерфейсу PAC (работа с мышью, оконные меню и пр.) и наличия большего количества оперативной памяти для реализации функций РАС. Графика,​ порождаемая РАС, полностью совместима с MSX1. 
 + 
 +При работе с РАС, наиболее предпочтительными являются компьютеры MSX2, имеющие аппаратуру Memory Mapper и более 64 кбайт оперативной памяти (RAM). Это связано с тем, что при наличии Memory Mapper, РАС размещает все свои оверлейные программные сегменты и полиэкран пользователя в мэппируемой памяти и не производит дополнительных обращений к диску во время работы. Тем не менее, РАС может работать и на компьютерах MSX2, имеющих только 64 кбайт RAM и 128 кбайт VRAM. В этом случае,​ полиэкран пользователя располагается в  VRAM (что несколько замедляет работу по сравнению с Memory Mapper), a программные сегменты подгружаются по мере необходимости с диска. 
 + 
 +РАС написан на языке С (компилятор BDS C) с использованием «Графической Библиотеки MSX для BDS C». 
 + 
 +3. ПОРЯДОК РАБОТЫ 
 + 
 +3.1 Для вызова РАС с диска, введите с клавиатуры компьютера:​ 
 +<​code>​A>​pac</​code>​ 
 +После этого РАС будет загружен в память и начнет работать. 
 + 
 +При этом, РАС будет использовать стандартную демонстрационную библиотеку знакомест (Patterns/​Colours Library), которая находится в нём самом. Если вы модифицируете эту библиотеку и захотите сохранить её в виде отдельного файла — воспользуйтесь функцией SAVE 
 +LIBRARY в меню РАС (файлам библиотек рекомендуется давать расширение .LIB при сохранении их на диске) 
 + 
 +Для того, чтобы познакомиться с возможностями PAC, загрузите в него файл DEMO.MNT, выбрав функцию LOAD в меню РАС (MNT — Multi-screen Name Table — полиэкран) и попробуйте модифицировать его. Если вы захотите сохранить полиэкран на диске, воспользуйтесь функцией ​ SAVE ALL NAME TABS в меню РАС (файлам полиэкранов рекомендуется давать расширение .MNT при сохранении их на диске). Если вы хотите сохранить отдельный экран - воспользуйтесь функцией 
 +SAVE SINGLE NAME TAB (используйте расширение .SNT). 
 + 
 +Пробуйте вызывать различные функции PAC и учитесь пользоваться ими — это не должно занять у Вас слишком много времени. 
 + 
 +3.2 Полный формат командной строки РАС: 
 +<​code>​ 
 +pac [l=libfile] [screenfile] 
 +</​code>​ 
 + Если вы разработали свою собственную библиотеку знакомест и полиэкран для неё (и,  конечно,​ сохранили их на диске!),​ то вы должны вызывать РАС, указывая имена Ваших файлов в командной строке РАС. Предположим,​ что Ваша библиотека называется MYPIC.LIB, а полиэкран — MYPIC.MNT, в этом случае командная строка вызова РАС будет выглядеть следующим образом:​ 
 +<​code>​ 
 +A>pac l=mypic.lib mypic.mnt 
 +</​code>​ 
 + 
 +Специальный пакетный файл P.BAT поможет Вам упростить вызов PAC: 
 +<​code>​ 
 +А>p mypic 
 +</​code>​ 
 + 
 +Одной из особенностей РАС является возможность загружать файлы ​ библиотек ​ знакомест,​ присоединяя их к уже загруженным,​ поэтому,​ если вы воспользуетесь функцией LOAD для загрузки библиотеки из меню РАС, когда РАС уже загружен в память и работает,​ вы присоедините «новую» библиотеку к «старой». «Новая» библиотека будет размещена в пространстве «старой»,​ начиная с позиции «первого свободного знакоместа» (там, где находится указатель «первого свободного» «старой» библиотеки) и будет добавляться к «старой»,​ за исключением всех повторяющихся знакомест (одинаковых паттернов,​ имеющих одинаковую окраску). 
 + 
 +Таким же образом вы можете загрузить в РАС экран, подготовленный другим редактором (например «Graphic Master» Sony) или Бейсиком. При этом РАС определит по первому байту файла, какие данные и в каком формате вы предлагаете ему загрузить и, если это экран Бейсика или библиотека знакомест — попытается присоединить их к уже загруженой библиотеке. В случае экрана Бейсика,​ РАС будет пытаться восстановить исходное изображение (конечно,​ насколько это будет возможно,​ исходя из наличия свободного места в уже загруженой библиотеке). 
 + 
 + 
 +Замечания. 
 + 
 +3.2.1. Как уже было указано,​ тип загружаемого файла распознается РАС автоматически исходя из первого байта файла (см. «Files» в «Help» меню РАС и раздел 5 данного документа). 
 + 
 +3.2.2. Вы можете сохранять отдельные экраны (файлы SNT) и загружать их в произвольные места полиэкрана (файла MNT), которые могут, в том числе, не совпадать с точными границами отдельных экранов. 
 + 
 +3.2.3. Файлы MNT могут быть сохранены в двух основных форматах:​ «Абсолютном» и «Переместимом» («Absolute» и «Relocatable»). 
 +«Абсолютный» формат является отображением памяти всего полиэкрана «строка за строкой» и используется в рамках «Библиотеки функций» для загрузки и дальнейшей работы со знакоместной ​  ​графикой. Ширина и высота полиэкрана (в отдельных экранах) являются неотъемлемой частью данных этого формата и автоматически восстанавливаются в РАС при загрузке файла с диска на основе данных,​ записанных в «абсолютный» файл при его сохранении. 
 +«Переместимый» формат является отображением памяти полиэкрана «экран за экраном»,​ и, поэтому,​ не связан жёстко с конфигурацией полиэкрана. «Переместимый» файл может быть загружен в любую конфигурацию полиэкрана (с любыми высотой и шириной) без её изменения. «Библиотека функций» не поддерживает загрузку «переместимых» полиэкранов и этот формат используется,​ в основном,​ для изменения размещения экранов в рамках РАС как альтернатива сохранению одиночных экранов (SNT) в виде отдельных файлов с последующей их одиночной загрузкой. Тем не менее, этот формат может быть эффективно использован в программах пользователя в том случае,​ когда не требуется скроллинг полиэкрана. 
 + 
 +3.2.4. Постарайтесь не использовать в Библиотеках знакоместа с латинскими буквами,​ цифрами и фрагментами рамок для других паттернов,​ когда создаёте свою собственную библиотеку. Это предотвратит временное искажение внешнего вида меню самого РАС (текущая версия РАС не защищает системную библиотеку знакомест,​ которая полностью доступна пользователю для любых модификаций). Эта рекомендация имеет смысл и применительно к «Библиотеке функций»,​ так как стандартная таблица перекодировки для вывода алфавитно-цифровых символов на экран с использованием функций putstrt(), tprintf() и др. ориентирована на существующее расположение этих символов в стандартной библиотеке знакомест. Тем не менее, это требование не является обязательным — вы можете полностью изменить стандартную библиотеку РАС — РАС будет продолжать работать (если, конечно,​ вы сможете работать с искажёнными меню РАС). 
 + 
 +3.3. Управление РАС 
 +РАС имеет два основных режима работы:​ «Меню» и «Компоновка» (Menu и Compose). 
 + 
 +Сразу после загрузки РАС, он переходит в режим Menu, в котором вы можете выбирать такие функции РАС, как COPY, CUT, PASTE,… или вызывать некоторые подсистемы,​ такие, как Pattern Editor+, простым нажатием на левую кнопку мыши с указаним стрелкой на выбранную Вами функцию. 
 + 
 +Для переключения РАС между режимами Menu/​Compose,​ нажимайте правую кнопку мыши. 
 + 
 +В режиме Compose все меню РАС исчезают с экрана и, используя кнопки ​ мыши, вы можете брать паттерны с экрана и располагать их там, где считаете необходимым (при этом РАС модифицирует только Name Table). 
 + 
 +Примечание:​ двойное нажатие на правую кнопку мыши (Double Click UNDO) в режиме Compose приводит к появлению/​исчезновению в верхней трети экрана библиотеки знакомест,​ из которой вы можете брать паттерны,​ которых в данный момент нет на экране. 
 + 
 +В основном,​ все режимы работы РАС могут быть выбраны при помощи мыши (Single-click,​ Double-click,​ DRAG — нажать кнопку и перемещать мышь до отпускания кнопки),​ но часть наиболее часто используемых функций продублирована при помощи клавиш клавиатуры (см. «Help» в меню РАС). Кроме того, скроллинг полиэкрана (MNT) может осуществляться ТОЛЬКО при помощи клавиш КУРСОРА (с использованием или без использования клавиши GRAPH). 
 + 
 +Лучший способ научиться — это практика:​ загрузите файл DEMO.MNT, просмотрите его (используя клавиши курсора и GRAPH), модифицируйте полиэкран в режиме Compose (перейдя в него при помощи UNDO), загрузите Pattern Editor+ (нажав ESC или вызвав эту подсистему из меню), модифицируйте Библиотеку знакомест,​ попробуйте Animaion (динамическую смену фаз)… ​  ​Может быть, РАС поможет Вам так же, как он помогает своему автору?​ 
 + 
 +4. ФОРМАТЫ ДАННЫХ 
 + 
 +Файлы, которые в настоящий момент могут быть подготовлены при помощи РАС и сохранены на диске, классифицируются следующим образом. 
 + 
 +1. Multi-screen Name Table (MNT) — полиэкран,​ состоящий из одиночных экранов общим количеством до 21 (каждый одиночный экран — Single-screen Name Table (SNT) 768 байт). Полиэкран может быть сконфигурирован пользователем с различными шириной и высотой,​ задаваемых в количестве SNT (см. «Screen Config» в меню РАС) и сохранён в различных вариантах:​ «Абсолютном» и «Переместимом» (см. выше). 
 + 
 +2. Singe-screen Name Table (SNT) — текущее положение окна физического экрана на полиэкране (MNT) — 768 байт Name Table. 
 + 
 +3. Library (LIB) — библиотека знакомест:​ pattern-библиотека (2048 байт) + colour-библиотека (2048 байт). При работе РАС и в большинстве других приложений библиотека чаще всего является общей для всех 3 частей экрана в Screen 2: верхней,​ средней и нижней. Однако,​ это не исключает того, что Ваша будущая программа сможет использовать до трёх независимых друг от друга различных библиотек для различных третей экрана. 
 + 
 +Как уже было отмечено выше, РАС сам различает форматы файлов,​ которые ему предлагают загрузить и сохраняет файлы с признаком формата сохранения. 
 + 
 +Для идентификации различных форматов записи файлов,​ создаваемых и загружаемых РАС, используется первый байт (первые байты) каждого файла. Ниже приводятся стандартные значения этого байта (байтов) 
 +с соответствующими комментариями. 
 + 
 +F7 — MNT в «Абсолютном» (строка за строкой MNT) формате. Последующие 2 байта являются шириной и высотой MNT в одиночных экранах (SNT). РАС поддерживает загрузку и сохранение таких файлов. 
 +F8 — Special. Использовался для разработки собственно РАС. РАС поддерживает только сохранение таких файлов. 
 +F9 — MNT в «Переместимом» (экран за экраном SNT) формате с шириной и высотой MNT. В настоящее время не поддерживается. Используется для совместимости со старыми версиями РАС только в режиме загрузки. 
 +FA — Sprites (2048 байт) — пока не поддерживается РАС. 
 +FB — SNT — 768 байт. РАС поддерживает загрузку и сохранение таких файлов. 
 +FC — MNT в «Переместимом» (экран за экраном SNT) формате. Нет байтов ширины и высоты MNT.  РАС поддерживает загрузку и сохранение таких файлов. 
 +FD — Библитека знакомест:​ Pattern Generator (2048 байт) + Colour Table (2048 байт) + 1байт. Последний байт является «указателем первого свободного» знакоместа для алгоритма автоматического размещения/​добавления знакомест РАС. РАС поддерживает загрузку и сохранение таких файлов. 
 +FE — Стандартный формат BSave/BLoad для VRAM Бейсика MSX. Следующие 3 слова (по 2 байта) являются адресами загрузки,​ конца данных и исполнительным адресом (не имеет смысла для VRAM). РАС поддерживает только загрузку таких файлов. 
 + 
 + 
 +5. РЕКОМЕНДАЦИИ ПО ИСПОЛЬЗОВАНИЮ 
 + 
 +РАС является достаточно ​ большой и сложной программой с простым интерфейсом пользователя. Так как теоретически в любой большой (и даже уже исправленой) программе всегда есть как минимум 3 ошибки,​ автор предполагает,​ что они есть и в РАС. Поэтому,​ в случае обнаружения этих ошибок при работе с РАС — просьба сообщить о них автору. Для того, чтобы эта информация принесла реальную пользу,​ при обнаружении ошибки нажмите,​ пожалуйста,​ клавишу SELECT и запишите ряд цифр, которые появятся в нижней строке экрана (клавиша SELECT включает и выключает встроеный механизм трассировки РАС). Эти цифры (вместе ​ с  номером ​ версии РАС, которую вы эксплуатируете и объёмом оперативной памяти Вашего компьютера) помогут автору при поиске причины нарушения нормальной работы РАС. 
 + 
 +</​code>​ 
 + 
 +</​hidden>​
  
-Программное средство (ПС) "​Маэстро"​ предназначено для создания высокоэффективных и кратких программ на языке С для компьютеров MSX и MSX2 и включает в себя такие средства программирования как параллельные процессы,​ окна, работа с манипулятором "​мышь",​ специализированные методы доступа и обработки графических данных и многое другое. 
-ПС "​Маэстро"​ может быть использовано для разработки учебных программ,​ компьютерных игр, системных и прикладных программ и для других приложений. 
  
-Написано на [[msx:​bds_c:​bds_c|]]. 
  
-{{msx_maestro.jpg?​350|}} \\ 
-Реклама в журнале "​Микропроцессорные средства и системы"​ №6, 1988 
  
 ====== Ссылки ====== ====== Ссылки ======
 +{{:​msx:​maestro:​maestro_glall.txt|}}
  
-[[https://​www.msx.org/​forum/​msx-на-русском/​железо/​самодельная-мышь-стандарта-msx-тёплая-ламповая-история?​page=1#​comment-375293|Самодельная мышь стандарта MSX. Тёплая ламповая история. | MSX Resource Center (Page 2/2)]]+{{:msx:​maestro:​maestro_glall-305.txt|}}
  
 +{{anchor:​microprocessor_means_and_systems_1988_06}}
 +<hidden Реклама в журнале "​Микропроцессорные средства и системы"​ №6, 1988>
 +{{msx_maestro.jpg?​1000|}} \\ [[https://​i.postimg.cc/​vmMr7cyF/​image.jpg|оригинал]] \\
 +{{msx_maestro_02.jpg?​1000|}} \\ [[https://​pic.maxiol.com/​images2/​1613586053.1054456127.72j.jpg|оригинал]]\\
 +Реклама в журнале "​Микропроцессорные средства и системы"​ №6, 1988
 +</​hidden>​
  
-{{tag>MSX Programming Rodionov_A_B}}+{{anchor:​mpc0398}} 
 +<hidden Реклама в журнале "​Мир ПК №3, 1989">​ 
 +Файл предоставил **Артем Читайло**
  
 +{{:​msx:​maestro:​mpc0398_maestro.jpg|}}
 +</​hidden>​
 +
 +
 +[[msxorg>​forum/​msx-на-русском/​железо/​самодельная-мышь-стандарта-msx-тёплая-ламповая-история?​page=1#​comment-375293|Самодельная мышь стандарта MSX. Тёплая ламповая история. | MSX Resource Center (Page 2/2)]]
 +
 +[[msxorg>/​node/​48305?​page=1#​comment-367498|Танцроид]]
 +
 +
 +{{tag>​MSX Programming Rodionov_A_B}}
msx/maestro/maestro.1604487773.txt.gz · Последние изменения: 2020-11-04 14:02 — GreyWolf