====== NestorBASIC ====== {{anchor:nbas111r}} {{anchor:nbas111e}} Это статья написана на основе документации {{nbas111e.txt|User's manual in english, version 1.11}}, [[https://raw.githubusercontent.com/Konamiman/MSX/master/SRC/NBASIC/nbas111e.txt|оригинал]] \\ Автор: Nestor Soriano (Konami Man), Декабрь 2004 Nestor Soriano также является автором [[msx:nextor:nextor|]] [[https://www.konamiman.com/msx/msx-e.html#nestorbasic|Официальная страница NestorBASIC]] Перевод документации выполнил: **ATroubleshooter**, 2021–2023 \\ [[github>/ATroubleshooter/MSX/blob/Russian-translation/SRC/NBASIC/nbas111r.txt|Перевод документации NestorBASIC version 1.11 на русский]] Оформление и корректура: **Алексей Сысоев** aka GreyWolf. /* {{nbasic_110.zip|NestorBASIC 1.10}} 58522 ef3f88b83b1e418c61ad0e9fc19dbf00 */ ~~TOC_HERE~~ ~~TOC wide 1-2~~ {{anchor:n1}} ====== 1. Что такое NestorBASIC ? ====== NestorBASIC — это набор подпрограмм(функций, процедур) в машинном коде, интегрированных в один файл, предназначенных для использования в программах на [[msx:basic:|Бейсике]]. NestorBASIC обеспечивает, без утраты совместимости с [[msx:x-basic:|]], следующую функциональность: * Полный доступ ко всей страничной оперативной памяти компьютера(всей памяти, в случае [[msx:dos:|]], всей свободной памяти в случае [[msx:dos2:|]]), вплоть до 4 Мб. * Доступ ко всей видеопамяти(VRAM), с возможностью пересылки блоков данных как в пределах VRAM, так и между VRAM и RAM. * Размещение программ [[msx:basic:|]] в страничной памяти, с возможностью выполнять переход из одной программы в другую с сохранением переменных. * Доступ к файлам на диске и непосредственно к физическим секторам, с возможностью чтения/записи напрямую в/из страничной RAM и VRAM. Поиск файлов, работа с директориями. * Сжатие и распаковка графики. * Проигрывание Moonblaster-музыки. Подгрузка samplekit'ов. * Воспроизведение звуковых эффектов на [[msx:psg:psg|PSG]](AY-3-8910). * Вызов подпрограмм в машинном коде, находящихся в [[msx:bios|BIOS]], [[msx:bios#sub|Sub-BIOS]], в основной области памяти [[msx:basic:|]], рабочей области системы, или в сегменте страничного ОЗУ. * Вызов функций [[msx:nestorman:|]], процедур [[msx:internestor_suite:|]] и [[msx:internestor_lite:|]]. Все имеющиеся функции доступны через один единственный [[msx:basic_dialogue_programming_language:101#usr|USR]] и массив целочисленных параметров, следовательно они полностью совместимы с [[msx:x-basic:|]]. Собственно, сам компилятор [[msx:x-basic:|]] содержится в [[#nbasicbin|файле]] ''NBASIC.BIN'', и автоматически загружается при [[#load|резидентной установке]] NestorBASIC. NestorBASIC загружается в сегмент ОЗУ, не используемый [[msx:basic:|]], так что нужен лишь небольшой объем основной памяти [[msx:basic:|]] (примерно 500 байт) для программы перехода. Остальная основная память [[msx:basic:|]] свободна для программы на Бейсике. {{anchor:n2}} ====== 2. Системные требования. Загрузка NestorBASIC ====== NestorBASIC работает на любой [[msx:msx_2|MSX2]]/[[msx:msx_2_plus|2+]]/Turbo-R с как минимум 128 кБ страничной памяти. В случае с [[msx:dos2:|]] нужен хотя бы один свободный сегмент ОЗУ в первичном [[msx:ram:ram#mapper|маппере]] (два, если собираетесь использовать проигрыватели музыки. См. [[#n8|раздел 8]] для подробностей). {{anchor:nbasicbin}} |<90%>| ^ Файл ^ Размер \\ (байт) ^ Контрольная сумма \\ MD5 ^ Описание ^ |{{nbasic_111.zip|NestorBASIC 1.11}}|58539|42f1a7d5d3fe2281c743f4283fc4f4a9|[[https://www.konamiman.com/msx/nbasic/NBASIC.BIN|оригинал]]| Этот {{nestorbasic_1.11.zip|архив}} содержит все исходные файлы для сборки. Для сборки из исходного текста рекомендуется использовать [[msx:compass:compass|среду разработки Compass]], либо кросс-ассемблер [[sjasm:sjasm]] на ПК. {{anchor:load}} Для загрузки NestorBASIC, просто выполните в [[msx:basic:]] команду: BLOAD"NBASIC.BIN",R Также можно выполнить вызов из файла автозапуска: 10 BLOAD"NBASIC.BIN",R:NEW Ни предварительных, ни последующих команд ''[[msx:basic_dialogue_programming_language:010#clear|CLEAR]]'' и ''[[msx:basic_dialogue_programming_language:101#def_usr#|DEFUSR]]'' не требуется. Если все прошло без ошибок, мы получаем следующее: - NestorBASIC и [[msx:x-basic:|]] загружены, каждый в свой сегмент ОЗУ, и готовы к работе. - Размер свободной основной памяти [[msx:basic:|]] уменьшился примерно на 500 байт, которые были заняты программой, осуществляющей переход в сегмент NestorBASIC. - Первый ''USR'' [''USR0''(параметр) или просто ''USR''(параметр)] указывает на вышеупомянутую программу перехода — это hook для вызова функций NestorBASIC. - Создан целочисленный массив параметров P. Этот массив используется для передачи параметров в функции NestorBASIC и приёма из них результатов, за исключением кодов ошибок. Коды ошибок возвращаются командой ''USR'' (функции для работы с файлами и функции обработки строк требуют собственный строковый массив, который нужно объявлять отдельно. См. [[#n4|раздел 4]] для подробностей). Первые пять элементов P инициализированы следующим образом: |<100% 5% 95%>| |P(0)|Количество доступных сегментов памяти, или код ошибки| |P(1)|Мажорная версия NestorBASIC| |P(2)|Минорная версия NestorBASIC, в формате BCD (должна показываться в шестнадцатеричном формате)| |P(3)|Мажорная версия [[msx:dos:|]]| |P(4)|Минорная версия [[msx:dos:|]], в формате BCD (должна показываться в шестнадцатеричном формате)| Число доступных сегментов ОЗУ всегда будет как минимум 5. Меньшее значение в P(0) будет отражать код ошибки, возникшей при резидентной установке NestorBASIC: |<100% 5% 95%>| |0|Компьютер не имеет страничной памяти, или в нем только 64кБ страничного ОЗУ| |1|Дисковая ошибка при чтении NestorBASIC или [[msx:x-basic:|]] из файла ''NBASIC.BIN''| |2|Нет свободных сегментов в первичном [[msx:ram:ram#mapper|маппере]]. Эта ошибка может появиться только под [[msx:dos2:|]])| |3|NestorBASIC уже установлен. Все переменные были переинициализированы| |4|Не определено в этой версии| После резидентной загрузки NestorBASIC можно резервировать память для других резидентных подпрограмм в обычном порядке, т. е. использовать команду ''[[msx:basic_dialogue_programming_language:010#clear|CLEAR]]'' для установки начала зарезервированной области. Тем не менее, в связи с тем, что NestorBASIC производит переключения слотов/сегментов в странице 2, и интерпретатор [[msx:basic:|]] располагает стек в области памяти ниже области строковых переменных и области, зарезервированной для пользователя, есть нижний предел для адреса, устанавливаемого командой ''[[msx:basic_dialogue_programming_language:010#clear|CLEAR]]''. А конкретно, нельзя зарезервировать память с адреса меньше, чем определяется данной формулой: &HC000 + (MAXFILES+1)*267 + FRE("") + 100 Также, помните, что команда ''[[msx:basic_dialogue_programming_language:010#clear|CLEAR]]'', как и загрузка/очистка/модификация программы на [[msx:basic:|]] стирает все переменные. В этом случае, массив P должен быть переопределён командой ''DEFINT P:DIM P(15)'', и это должно быть сделано вне блоков компиляции (далее — турбо-блоков). Также, должен быть переопределен массив F, если требуется (см. [[#n4|раздел 4]] для подробностей о массиве F). Если нужно объявить массив F внутри турбо-блока, необходимо сделать это в первой строке турбо-блока, чтобы обеспечить работу функций NestorBASIC: 10 'save"autoexec.bas" 20 BLOAD"nbasic.bin",R:IF P(0)<5 THEN PRINT "Error!":END 30 CLEAR 100:DEFINT P:DIM P(15) 40 _TURBO ON(P()) 50 DIM F$(1) 'See section 4 ... 65000 _TURBO OFF 65010 RUN"next.bas" 10 'save"next.bas" 20 DEFINT P:DIM P(15) 30 _TURBO ON(P()) 40 DIM F$(0) 'If F$(1) is not needed. See section 4.1 ... 65000 _TURBO OFF Также, помните, что нулевой ''USR'' всегда зарезервирован за NestorBASIC как служебный вызов. Вызовы с ''USR1'' по ''USR9'' не заняты. {{anchor:n3}} ====== 3. Логические сегменты ====== {{anchor:n31}} ===== 3.1. Что такое логический сегмент? ===== Страничное ОЗУ компьютеров MSX организовано в сегменты по 16 кБ. Каждый слот ОЗУ содержит определённое число S сегментов (нумеруемых от 0 до S-1), доступных, когда они подключены в адресное пространство активного слота памяти, что контролируется через порты с &HFC по &HFF. При загрузке NestorBASIC, все имеющиеся слоты сканируются на наличие ОЗУ (всей памяти в случае [[msx:dos:|]], всей свободной памяти в случае [[msx:dos2:|]]), и строится таблица сегментов. В этой таблице, все найденные сегменты регистрируются в пары слот-сегмент (под [[msx:dos2:|]], сегменты сначала выделяются). NestorBASIC идентифицирует каждую из этих пар по порядковому номеру в таблице. Этот номер называется номером логического сегмента, и позволяет пользователю оперировать всей доступной памятью в последовательном виде, не заботясь ни о номерах слотов, ни о номерах физических сегментов, в которых она находится. Например, представим MSX с 128 кБ внутренней RAM (8 сегментов) и [[msx:ram:ram#mapper|маппер]] на 1024 кБ (64 сегмента) во внешнем слоте. Тогда, после инициализации NestorBASIC, в случае [[msx:dos:|]], пользователю будет доступно 72 логических сегмента, под номерами от 0 до 71, и достаточно указать этот номер в соответствующих функциях NestorBASIC для их использования. Номера физических слотов и сегментов уже не потребуются. Адресное пространство логического сегмента (далее — просто «сегмента») от &H0000 до &H3FFF. Если заданы более высокие адреса при вызове функций NestorBASIC, они будут преобразованы. То есть, адреса &H4000–&H7FFF, &H8000–&HBFFF и &HC000–&HFFFF эквивалентны &H0000–&H3FFF при доступе к сегментам ОЗУ через NestorBASIC. Все сегменты доступны для чтения и записи, но есть важные ограничения по отношению к первым шести: - Сегмент 0 содержит собственно NestorBASIC, и лишь небольшая область ОЗУ остаётся доступной для пользователя в конце него. Используйте функцию 1 чтобы получить начальный адрес этой области (описание функции см. в [[#n10|разделе 10]]). - Сегмент 1 содержит компилятор [[msx:x-basic:|]]. Можно перезаписать этот сегмент только в том случае, если Вы не собираетесь использовать компилятор. - Сегмент 2 всегда подключён к 2 странице (адреса &H8000–&HBFFF), и содержит исполняемую программу на [[msx:basic:|]] и часть её переменных. - Сегмент 3 всегда подключён к странице 3 (адреса &HC000–&HFFFF), и содержит рабочую область системы и часть переменных программы на [[msx:basic:|]]. Будьте внимательны при записи сюда. - Сегмент 4 используется как служебный буфер некоторыми функциями NestorBASIC. Вы можете использовать этот сегмент для ваших данных, если Вы не обращаетесь к этим функциям NestorBASIC. См. [[#n10|раздел 10]] или [[#a1|приложение 1]] чтобы узнать, какие функции используют этот сегмент. - Сегмент 5, если он есть, изначально свободен, и не используется NestorBASIC. Но если используются музыкальные плееры, при инициализации они занимают этот сегмент. См. [[#n8|раздел 8]] для подробностей. Все оставшиеся сегменты — в полном распоряжении программиста. Внимание: логические сегменты 2 и 4 поменялись ролями при переходе с версии 0.07 на версию 1.00 NestorBASIC. В версии 0.07 и ранее, сегмент 2 был служебным буфером NestorBASIC, а сегмент 4 соответствовал странице 2. При использовании функций обмена блоками данных, нужно быть осторожным, чтобы сумма адреса назначения и длины пересылаемого блока не превысила адрес &H3FFF (например, не пытайтесь переслать &H2000 байт указывая адрес &H3000 как адрес назначения). В таком случае, сегмент 0 или сегмент 3 будут перезаписаны, и результат будет непредсказуем. Внимание: с помощью [[#f80|функции 80]] можно указать NestorBASIC зарезервировать меньше сегментов памяти, чем суммарно доступно. Это полезно под [[msx:dos2:|]], когда одновременно используются другие резидентные программы, требующие выделения памяти (например, [[msx:basic_dialogue_programming_language:009#ramdisk|RAM-диск]] или [[msx:nestorman:nestorman|]]). Описание функций см. в [[#n10|разделе 10]]. {{anchor:n32}} ===== 3.2. Использование VRAM в качестве логических сегментов ===== NestorBASIC позволяет использовать VRAM для ваших данных, путём эмуляции дополнительных сегментов ОЗУ. Если NestorBASIC показывает, что располагает S сегментами памяти, то номера сегментов с 0 по S-1 соотносятся со страничной RAM, тогда как номера сегментов с S по S+7 (или S+3, в зависимости от объёма видеопамяти, 128 кБ или 64 кБ) соотносятся с VRAM. Вернёмся к компьютеру из предыдущего примера. После резидентной загрузки NestorBASIC или после вызова функции 1 (см. список функций) получаем P(0)=72. Это значит (предполагая, что у нас 128 кБ видеопамяти), что сегменты с 72 по 79 соотносятся с VRAM. Соответствие между сегментами и адресами VRAM обратное: сегменты с меньшими номерами соответствуют наибольшим адресам VRAM. Это сделано так для того, чтобы помочь программисту при освобождении сегментов VRAM, соответствующих области отображения: это будет последний сегмент, при работе в текстовом режиме или при использовании лишь одной страницы в графическом режиме. Вернёмся к предыдущему примеру: компьютеру с 72 сегментами RAM и 128 кБ VRAM. Если программа работает в текстовом режиме, используются только первые 2000 байт VRAM: это видео-ОЗУ соответствует последнему сегменту VRAM, под номером 79. В этом случае, программист может свободно использовать сегменты с 72 по 78, и диапазон доступных сегментов будет 0–78, без необходимости пропускать какой-либо сегмент внутри этой последовательности. Если программа работает в ''SCREEN 5'' и использует только графическую страницу 0, диапазон сегментов будет с 0 по 77; в ''SCREEN 7'' он будет с 0 по 75, и т.д. Конечно, NestorBASIC также имеет функции для работы с VRAM напрямую, без эмуляции в ней сегментов RAM. Эти функции позволяют пересылать данные VRAM ↔ RAM и VRAM ↔ файл. Внимание: сегменты VRAM могут использоваться — как и обычные сегменты RAM — для размещения данных и программ на [[msx:basic:|]], а также для блоковых операций обмена с диском и сегментами RAM. Но учтите, что сегменты VRAM не могут быть использованы для: * Сжатия/распаковки графики * Исполнения программ в машинном коде * Исполнения прерываний, определяемых пользователем. * Воспроизведения звуковых эффектов на [[msx:psg:psg|PSG]](AY-3-8910) * Воспроизведения музыки Если Вы попытаетесь использовать сегменты VRAM для какой-то из этих целей, функция вернёт ошибку «несуществующий сегмент». {{anchor:n33}} ===== 3.3. Сегмент 255 ===== Логический сегмент 255 имеет особое предназначение. Он соотносится не с каким-то конкретным сегментом RAM или VRAM, а с основной памятью [[msx:basic:|]], то есть — c ОЗУ используемым [[msx:basic:|]] по адресам &H8000–&HFFFF (к нему не применяются ни ограничения, ни преобразования адресов в диапазон &H0000—&H3FFF, как к другим сегментам). Это удобно использовать для обмена данными между каким–либо сегментом и переменной [[msx:basic:|]] или массивом переменных: 1 'Copy 10 bytes from segment 7, begin address &H1000, 2 'to integer array D. 3 '(See section 10 for detailed functions specification) 4 ' 10 DEFINT D:DIM D(4) '5 integer data = 10 bytes 20 P(0)=7 'Source segment 30 P(1)=&H1000 'Source begin address 40 P(2)=255 'Destination segment=BASIC main RAM 50 P(3)=VARPTR(D(0)) 'Destination begin address=D array 60 P(4)=10 'length 70 J=USR(10) 'Call to function 10 (block transfer between segments) {{anchor:n34}} ===== 3.4. Карта сегментов ===== Резюмируя данный раздел, предоставим весь список имеющихся сегментов и их описание. S — это количество сегментов, возвращаемое в P(0) при резидентной загрузке NestorBASIC или при вызове функции ''USR0(1)'' |<65% 20% 40% 40%>| ^№^Назначение^| |0|Сегмент NestorBASIC|| |1|Сегмент [[msx:x-basic:|]]|| |2|Основная память [[msx:basic:|]], страница 2 (&H8000–&HBFFF)|| |3|Основная память [[msx:basic:|]], страница 3 (&HC000–&HFFFF)|| |4|Сегмент служебного буфера|| |5 по S-1|Память, доступная программе пользователя (если S>5) \\ Если загружен музыкальный плеер, он находится в сегменте 5. См. [[#n8|раздел 8]].|| | ^VRAM^VRAM 64 кБ^ |S|&H1C000–&H1FFFF|&HC000–&HFFFF| |S+1|&H18000–&H1BFFF|&H8000–&HBFFF| |S+2|&H14000–&H17FFF|&H4000–&H7FFF| |S+3|&H10000–&H13FFF|&H0000–&H3FFF| |S+4|&H0C000–&H0FFFF| — | |S+5|&H08000–&H0BFFF|:::| |S+6|&H04000–&H07FFF|:::| |S+7|&H00000–&H03FFF|:::| |S+8 до 254|Отсутствуют (если S+8<255)|| |255|Основная память [[msx:basic:|]] (&H8000–&HFFFF)|| {{anchor:n35}} ===== 3.5. Ошибки ===== Все функции доступа к RAM и/или VRAM возвращают код ошибки -1 в следующих случаях: * указан номер отсутствующего сегмента памяти; * попытка доступа к адресу VRAM выше &HFFFF в компьютерах с 64 кБ VRAM; * указан сегмент VRAM или 255-й сегмент в функциях, которые поддерживают только обычные сегменты RAM. {{anchor:n4}} ====== 4. Доступ к диску ====== NestorBASIC включает функции для работы с файлами на диске и доступа к другим возможностям [[msx:dos:]], а именно: * создание/удаление/переименование/поиск файлов; * чтение/запись файлов в/из любого сегмента или области VRAM; * чтение/запись секторов в/из любого сегмента или области VRAM; * определение ёмкости диска, свободного пространства. Функции, доступные только под [[msx:dos2:|]]: * перемещение файлов, чтение/установка атрибутов файла; * получение/смена текущего рабочего диска/каталога (директории); * определение ёмкости/создание RAM-диска. {{anchor:n41}} ===== 4.1. Массив F$ ===== Для передачи имён файлов и директорий, эти функции задействуют массив строковых переменных ''F$''. Четыре из них — поиск, переименование и перемещение файлов, а также обработка пути файлов требуют двух строковых элементов, для чего нужно, чтобы был объявлен массив ''F$'' из двух элементов ''DIM F$(1)''. Остальным функциям требуется только одна строка; поэтому, если не будет использоваться ни одна из вышеперечисленных четырех функций, можно объявить массив ''F$'' только из одного элемента ''DIM F$(0)''. Особенно это рекомендуется в случае использования [[msx:x-basic:|]], потому что внутри турбо-блоков каждая строка занимает 256 байт, независимо от её реальной длины. Также, нужно иметь в виду, что массив ''F$'' должен объявляться сразу же после начала турбо-блока, следующей строкой: 1000 _TURBO ON(P()) 1010 DIM F$(1) или DIM F$(0) ... 65000 _TURBO OFF ВАЖНО: Строковые переменные, определенные вне турбо-блока, равно как и другие переменные, не передаются в турбо–блок, и восстанавливаются после его завершения! {{anchor:e41}} __//Пример//__. 10 A$="Outside" 20 _TURBO ON 30 A$="Inside":PRINT A$ 40 _TURBO OFF 50 PRINT A$ run Inside Outside [[+tab|wmsx>?DISK_FILES=/_media/msx/nestor_basic/examples.zip&BASIC_RUN=41.bas|Запустить в WebMSX]] С NestorBASIC это правило по-прежнему верно, но со строками ''F$()'' требуется дополнительная предосторожность. Если массив ''F$'' использовался вне турбо-блока и будет затем объявляться внутри него — следующая строка должна быть помещена перед ''CALL TURBO ON'': F$(0)=F$(0)+"":F$(1)=F$(1)+"" Эта строка не нужна, если не требуется сохранять прежнее состояние ''F$'', или если Вы не будете объявлять ''F$'' внутри турбо–блока. Ещё одно ограничение ''F$(0)'' и ''F$(1)'' — их длина ограничена 80 символами; остальные символы будут просто отброшены функциями NestorBASIC, которым эти строки поданы в качестве входных параметров. Все эти ограничения не действуют для индексов выше чем 1, если в массиве ''F$'' больше элементов; то есть, Вы можете объявить ''F$'' из более чем двух элементов, и использовать элементы ''F$(2), F$(3)''… как обычно. {{anchor:n42}} ===== 4.2. Ошибки ===== Помимо ошибки -1, описанной в [[#n35|разделе 3]], функции работы с диском имеют собственные коды ошибок. Следующие ошибки могут появиться только под [[msx:dos:|]]: |<100% 5% 95%>| ^1|Единый код ошибки [[msx:dos:|]]. Он может быть вызван следующими причинами: * Файл не найден. * Неверное имя файла. * Файл уже существует (при переименовании). * Неверное имя диска (когда в составе пути файла). * Достигнут конец файла при чтении из файла. * Диск полон. * Корневая директория полна. * Функция не доступна под [[msx:dos:|]]. Под [[msx:dos2:|]], каждая из вышеперечисленных ошибок имеет свой собственный код, никогда не равный 1.| ^2|Неверный номер файла (нет открытых файлов с таким номером).| ^3|Слишком много открытых файлов. Максимальное число одновременно открытых файлов можно узнать посредством функции 1.| Следующие ошибки одинаковы под [[msx:dos:|]] и [[msx:dos2:|]], и имеют те же коды ошибок, что и [[msx:basic_dialogue_programming_language:205|их эквиваленты]] в [[msx:basic:basic|]]: |<100% 5% 95%>| ^60|Неисправная FAT| ^62|Неверный диск (при изменении рабочего диска).| ^68|Диск защищен от записи.| ^69|Физическая ошибка диска.| ^70|Диск отсутствует.| Специфичные для [[msx:dos2:|]], ошибки: |<100% 5% 95%>| ^222|Не достаточно свободной памяти для создания RAM-диска для открытия файла.| ^219|Неверный диск (будучи частью пути или имени файла).| ^218|Неправильное имя файла.| ^217|Неправильный путь.| ^215|Файл не найден.| ^214|Каталог (директория) не найден.| ^213|Корневая директория заполнена.| ^212|Диск заполнен.| ^211|Файл уже существует (при переименовании или перемещении файла).| ^210|Некорректная операция перемещения директорий (каталог не может быть перемещён в один из своих подкаталогов).| ^209|Файл только для чтения (при попытке записи в файл).| ^208|Каталог не пуст (при попытке удаления каталога).| ^207|Некорректные атрибуты (при установке атрибутов файла/директории).| ^206|Некорректная операция с "." или ".."| ^205|Существует системный файл с таким именем(при создании файла, любой существующий файл с таким именем автоматически удаляется, если только у него не установлен атрибут «системный»).| ^204|Директория с таким именем уже существует (аналогично случаю с системными файлами).| ^203|Файл с таким именем уже существует (при создании каталога).| ^202|Файл открыт (при удалении, переименовании или перемещении файла, или при изменении атрибутов с прямым указанием имени файла).| ^199|Достигнут конец файла (при чтении из файла).| ^196|Слишком много открытых файлов (при открытии файла).| ^195|Неправильный номер файла (больше 63).| ^194|Неверный номер файла (не принадлежит ни одному открытому файлу).| ^188|RAM-диск уже существует (при создании RAM-диска).| ^187|RAM-диск не существует (при удалении RAM-диска).| {{anchor:n5}} ====== 5. Сжатие и распаковка графики ====== NestorBASIC включает функции для сжатия графических данных из VRAM в RAM, и распаковки из RAM в VRAM. Формат сжатия тот же самый, что используется в процедуре вывода логотипа Sunrise, он работает по–байтно по следующему принципу: |Неповторяющиеся байты (до 63) \\ &B00nnnnnn &Hdd .. &Hdd \\ &Bnnnnnn это количество байт, &Hdd это сами байты| |Повторяющиеся байты (до 63 раз): \\ &B01nnnnnn &Hdd \\ &Bnnnnnn это количество повторений байта, &Hdd повторяемый байт| |Повторяющийся байт (до 16383 раз): \\ &B10nnnnnn &Bnnnnnnnn &Hdd \\ &Bnnnnnnnnnnnnnn количество повторений байта, &Hdd повторяемый байт| |Маркер окончания данных: \\ &B11000000 = &HC0| (Де)компрессия осуществляется в последовательные сегменты; то есть, после (де)компресии из/в адреса &H3FFF сегмента S, процесс продолжается с адреса &H0000 сегмента S+1. {{anchor:n51}} ===== 5.1 Ошибки ===== Функции компрессии/декомпрессии графики могут возвращать следующие коды ошибок: |<100% 5% 95%>| ^-1|Ошибка при сжатии или распаковке. Задан несуществующий сегмент, сегмент VRAM или 255-й. Также, эта ошибка появляется при указании некорректного адреса VRAM в любом из входных параметров.| ^5|Ошибка при упаковке. Недостаточно сегментов для сжатия всего изображения.| ^6|Ошибка при распаковке. Найдены некорректные данные, или закончились сегменты, прежде чем встретился маркер окончания данных.| {{anchor:n6}} ====== 6. Размещение программ на Бейсике в ОЗУ и их запуск ====== NestorBASIC включает функции, которые позволяют Вам помещать программы на Бейсике в любой сегмент RAM или VRAM, актуализировать или запускать их, не теряя переменные исходной программы (из которой произведен переход в новую). ВНИМАНИЕ: Чтобы использовать данные функции, нужно изменить адрес начала Бейсик-программы в основной памяти [[msx:basic:|]] с &H8000 на &H8003; это действие должно быть выполнено лишь однократно, и обязательно ПЕРЕД загрузкой NestorBASIC. Это можно сделать двумя способами: * В интерактивном режиме, напечатав следующие команды: POKE &HF676,4 POKE &H8003,0 NEW * Из программы на Бейсике. Этот способ лучше, так как в этой же программе можно, следом, загрузить NestorBASIC. Первая строка программы должна быть такой: 1 'program.bas 10 IF PEEK(&HF676)<>4 THEN POKE &HF676,4:POKE &H8003,0:RUN"program.bas" 20 'From here, you can load NestorBASIC Когда Вы актуализируете или запускаете программу, размещенную в сегменте, NestorBASIC сохраняет все переменные и массивы в сегменте 4; затем, копируется программа из желаемого сегмента в основную память [[msx:basic:|]], и все ранее сохраненные переменные помещаются после программы, после чего обновляются соответствующие указатели в рабочей области [[msx:basic:|]]. И, наконец, будет осуществлено выполнение программы с первой строки, либо переход в интерактивный режим — в зависимости от примененной функции (запуск или актуализация). Для того, чтобы программу на Бейсике можно было держать в сегменте и, в последствии, актуализировать или запустить, она должна там храниться со специальным заголовком, содержащим информацию о её длине, которая требуется для конкатенации уже существующих переменных с новой программой. Есть функция NestorBASIC, которая позволяет сохранить в файл активную программу с таким заголовком. В дальнейшем, просто загрузите этот файл в какой-нибудь сегмент с помощью дисковой функции, и программа готова к использованию — её можно актуализировать или выполнить в любой момент. {{anchor:n61}} ===== 6.1 Ошибки ===== Очевидно, что если исполняется команда или строка, следующая за USR-функцией, которая актуализирует или запускает другую программу на BASIC, то это означает, что мы находимся в состоянии ошибки. Возможна одна из двух ошибок: |<100% 5% 95%>| ^-1|Заданный сегмент не существует. Эти функции поддерживают сегменты VRAM, но не сегмент 255.| ^-2|Памяти MSX-BASIC не достаточно для новой программы и переменных. Случается, если актуализируемая/запускаемая программа больше, чем исходная.| {{anchor:n7}} ====== 7. Различные прочие функции ====== В этой группе собраны функции, предназначенные для: * Вызова подпрограмм в машинном коде, находящихся в [[msx:bios|BIOS]], [[msx:bios#sub|Sub-BIOS]], в основной памяти Бейсик, рабочей области системы или в сегменте ОЗУ (так называемые «пользовательские подпрограммы»). * Размещения строковых переменных в сегментах RAM и извлечения их оттуда. * Вывода на экран строковых переменных в графическом режиме. * Управления миганием (blink mode) в ''SCREEN 0'' * Назначения пользовательских прерываний (программы в машинном коде, находящиеся в сегменте RAM, выполняемые каждое прерывание по таймеру 50/60 Гц). * Воспроизведения звуковых эффектов на PSG(AY-3-8910), созданных в SEE версий 3.xx Некоторые из этих функций требуют строковый массив F$ для передачи параметров и возврата результатов, в дополнение к целочисленному массиву P. Больше подробностей о массиве F$ см. в [[#a4|разделе 4]]. Некоторые из внутренних процедур NestorBASIC могут вызываться из других машинных подпрограмм пользователя и использоваться прерыванием, определяемым пользователем. См. [[#a2|приложение 2]] для детального описания использования этих процедур. Редактор SEE (sound effects editor) для создания звуковых эффектов под PSG был разработан группой Fuzzy Logic, и использование звуковых эффектов, сделанных в этом редакторе, в коммерческих продуктах подразумевает отчисление небольшой суммы авторам. Больше деталей в [[#a4|приложении 4]]. {{anchor:n8}} ====== 8. Воспроизведение музыки ====== FIXME {{:msx:nestor_basic:nbasic_nplayer.zip|Плеер nplayer}}, [[github>Konamiman/MSX/tree/master/SRC/NBASIC/nplayer|оригинал]] {{ :msx:nestor_basic:nbasic_samples.zip|Примеры}}, [[github>Konamiman/MSX/tree/master/SRC/NBASIC/samples|оригинал]] {{anchor:n81}} ===== 8.1. Инициализация музыкального плеера ===== NestorBASIC включает музыкальные проигрыватели Moonblaster 1.4 и Moonblaster Wave для MoonSound версии 1.05 Эти плееры не загружаются автоматически вместе с NestorBASIC: вследствие своего большого размера, они не помещаются в сегмент ОЗУ NestorBASIC, и должны загружаться в отдельный сегмент. Поэтому, чтобы использовать плеер, его нужно загружать директивно. Одновременно может быть загружен лишь один плеер. [[#f71|Функция 71]] загружает и инициализирует желаемый плеер, оставляя его готовым к работе. Эта функция проверяет наличие 5-го сегмента и принадлежность его к первичному мапперу: если это так, то плеер загружается в этот сегмент, после чего сегмент становится не доступен для программы пользователя. Если сегмент 5 не существует, или подключён не к первичному мапперу, плеер не будет загружен, и функция выдаст ошибку. [[#nbasicbin|Файл]] ''NBASIC.BIN'' содержит два варианта проигрывателя Moonblaster Wave: один для [[msx:msx_2|MSX2]] / [[msx:msx_2_plus|2+]] и Turbo-R в режиме Z80, а другой для Turbo-R в режиме R800. Если компьютер это Turbo-R, то NestorBASIC определяет, какой вариант загружать, в соответствии с тем, в каком режиме работает процессор в момент вызова [[#f71|функции 71]]. Заметьте, что если произведено переключение режима процессора, эту функцию нужно вызвать заново, чтобы загрузить соответствующий плеер: вариант для Z80 не работает в режиме R800, а вариант для R800 привносит ненужное замедление системы в режиме Z80. После того, как плеер загружен, происходит поиск звуковых устройств, и все найденные помечаются как активные. Подробности о включении и отключении звуковых устройств см. в описании [[#f73|функции 73]]. {{anchor:n82}} ===== 8.2. Возможности плеера ===== Как только плеер загружен, он может использоваться функциями NestorBASIC для: * Начала проигрывания музыки, предварительно загруженной в сегмент RAM (сегменты VRAM не поддерживаются). * Остановки воспроизведения музыки. * Паузы/продолжения воспроизведения музыки. * Постепенного затухания музыки, с выбором скорости затухания. * Получения информации о воспроизводимой музыке (сегмент и начальный адрес, по которому она находится, название мелодии, набор сэмплов (samplekit) или набор PCM-инструментов (wavekit), текущая позиция и темп). * Получения сведений о обнаруженных звуковых устройствах. * Отключения звуковых устройств, чтобы они не задействовались, несмотря на то, что были обнаружены. * Загрузки samplekit-а музыкальной композиции или wavekit-а для Moonsound из файла. Во время проигрывания музыки, все функции NestorBASIC работают как обычно, включая проигрывание [[msx:psg:psg|PSG]] эффектов и использование прерываний, определяемых пользователем. Если NestorBASIC выгрузить из памяти, то воспроизводимая музыка будет автоматически остановлена. Плеер Moonblaster 1.4 помещается в 4,5 кБ, следовательно — адресное пространство с &H1200 по &H3FFF сегмента 5 остаётся свободно, и может использоваться, например, для хранения воспроизводимой музыки. Это не работает в случае с плеером Moonblaster Wave, который занимает 5 сегмент полностью. Музыкальные композиции Moonblaster 1.4 должны помещаться в один сегмент, поэтому их размеры ограничены 16кБ. Мелодии Moonblaster Wave могут занимать несколько сегментов подряд, максимум 3: если при разборе воспроизводимых аудиоданных NestorBASIC доходит до адреса &H3FFF, процесс продолжается с адреса 0 следующего сегмента. Чтобы загрузить муз. композицию Moonblaster Wave из файла, можно воспользоваться следующим примером: 1000 'Loading a music through consecutive segments, 1010 'starting in segment S, address A 1020 F$(0)="music.mwm":P(2)=S:P(3)=A 1030 E=USR(31):IF E<>0 THEN 10000 1040 P(4)=&H4000:E=USR(33) 1050 IF (E<>0 AND E<>1 AND E<>199) THEN 10000 1060 IF E=0 THEN P(2)=P(2)+1:P(3)=0:GOTO 1040 1070 E=USR(32):IF E<>0 THEN 10000 ... 10000 'Disk error E handling routine ... ВНИМАНИЕ: Композиция Moonblaster Wave может располагаться начиная с любого адреса в сегменте, потому что он продолжится в начале следующего сегмента. Тем не менее, как минимум первые 800 байт муз. композиции, содержащие таблицу паттернов и различные указатели, должны целиком быть помещены в один, начальный сегмент. {{anchor:n83}} ===== 8.3 Ошибки ===== Функции проигрывания музыки могут возвращать следующие коды ошибок: |<100% 5% 95%>| ^7|Возвращается функцией активизации аудио-чипов, функцией паузы и функцией затухания, если если какой-то из входных параметров некорректен.| ^12|Возвращается функцией старта воспроизведения и функцией включения аудио-чипов, если плеер не загружен. Остальные функции не выдадут ошибку в этом случае, они просто не сделают ничего| Следующие ошибки могут произойти при выполнении функции запуска воспроизведения: |<100% 5% 95%>| ^-1|Указанный сегмент не существует, соотносится с VRAM, или это 255 сегмент.| ^12|Плеер не загружен.| ^13|Музыка была записана в режиме EDIT и не может быть воспроизведена (плеер Moonblaster 1.4). \\ По данному адресу нет композиции Moonblaster Wave, или там находится композиция Moonblaster Wave, записанная в режиме EDIT (плеер Moonblaster Wave).| ^14|Уже проигрывается другая музыка в этот момент.| Функция загрузки wavekit для Moonsound, помимо ошибок работы с диском, может вернуть такую ошибку: |<100% 5% 95%>| ^15|По данному смещению в указанном файле нет wavekit для Moonblaster Wave, или там находится wavekit, сохранённый не в режиме USER.| :!: ВНИМАНИЕ: Плеер Moonblaster 1.4 не умеет различать, являются ли данные по конкретному адресу в действительности композицией Moonblaster 1.4, и лишь всецело полагается на первый байт для определения того, что это данные композиции, сохранённой в режиме EDIT. Плеер Moonblaster Wave не имеет этой проблемы. Функция загрузки плеера выдаёт такие же коды ошибок, как и функции для работы с диском, а также код -1 — если сегмент 5 не существует или не принадлежит первичному мапперу. ДЛЯ СПРАВКИ: Муз. композиции Moonblaster Wave могут быть сохранены в файл в режимах EDIT и USER. Файлы, сохранённые в режиме EDIT, содержат максимум информации о композиции, и могут быть воспроизведены только в самом трекере (музыкальном редакторе). Файлы, сохранённые в режиме USER, могут быть проиграны плеерами, и пригодны для встраивания в сторонние программы. Они предельно компактны, из них исключена вся избыточная информация — незадействованные в мелодии паттерны/инструменты/тоны. Названия инструментов и тонов также не сохраняются. {{anchor:n9}} ====== 9. Взаимодействие с NestorMan и InterNestor Suite/Lite ====== {{:msx:msxdos2-logo.svg?100&nolink|MSX-DOS 2}} {{:msx:unapi:tcpip-unapi.svg?140&nolink|UNAPI}} NestorBASIC имеет специальные функции, которые позволяют взаимодействовать с [[msx:nestorman:|]] (резидентный динамический менеджер памяти для [[msx:dos2:|]]), пакетом [[msx:internestor_suite:|]] (стек TCP/IP для [[msx:dos2:|]]) и [[msx:internestor_lite:|]] (стек TCP/IP для [[msx:dos:]]), если эти программы запущены. Таким образом, возможна разработка приложений на Бейсике, которые используют динамические блоки памяти и связанные списки, а также Internet–приложения. Чтобы узнать, запущен ли [[msx:nestorman:nestorman|]] и [[msx:internestor_suite:|]], можно воспользоваться [[#f91|функцией 81]]. Процедура проверки наличия загруженного [[msx:internestor_lite:|]] детально описана в [[#n94|разделе 9.4]]. ВНИМАНИЕ: [[msx:nestorman:|]] и [[msx:internestor_suite:|]] / [[msx:internestor_lite:|]] имеют собственную документацию, описывающую их функции и процедуры. Эти программы доступны [[http://msx.konamiman.com/msx/msx-e.html|здесь]]. ---- {{anchor:tcpcon}} {{:msx:nestor_basic:tcpcon.lzh|TCPCON}}, [[https://web.archive.org/web/20210328101831if_/https://www.konamiman.com/msx/nbasic/tcpcon.lzh|оригинал]] {{anchor:n91}} ===== 9.1. Сегменты NestorBASIC и сегменты NestorMan ===== [[msx:nestorman:|]] реализует систему логических сегментов, очень похожую на ту, что применяется в NestorBASIC. Оба пространства сегментов, NestorBASIC и [[msx:nestorman:|]], полностью независимы друг от друга, за несколькими исключениями: * Сегменты 0, 1, 2 и 3 являются общими для NestorBASIC и [[msx:nestorman:|]] (в документации к [[msx:nestorman:|]] эти сегменты называются «TPA segments»). * Если, при резидентной загрузке NestorBASIC, [[msx:nestorman::|]] запущен — тогда логический сегмент 4 NestorBASIC выделяется не с использованием механизмов [[msx:dos2:|]], как остальные сегменты. Вместо этого, используется [[#f7|функция 7]] [[msx:nestorman:|]]; таким образом, 4-му сегменту NestorBASIC присваивается, в свою очередь, номер сегмента [[msx:nestorman:|]] (этот номер можно узнать посредством [[#f81|81-й функции]] NestorBASIC). Этот сегмент зарезервирован установкой атрибута «exclusive», и поэтому не используется [[msx:nestorman:|]] для выделения блоков памяти. Если [[msx:nestorman:|]] и/или [[msx:internestor_suite:|]] будут использоваться вместе с NestorBASIC, рекомендуется ограничить, с помощью [[#f80|функции 80]], количество сегментов RAM, которые будут использоваться NestorBASIC. В противном случае, NestorBASIC зарезервирует для себя все доступные сегменты, и [[msx:nestorman:|]] не сможет задействовать резервы ОЗУ (необходимые для выделения блоков памяти, создания связанных списков и для отправки/получения данных в/из Интернета). Для вызова функций [[msx:nestorman:|]] можно использовать [[#f82|82-ю функцию]]; или можно использовать [[#f58|58-ю функцию]], указав хук EXTBIO (&HFFCA) в качестве адреса перехода, занеся &H2202 в регистровую пару DE, и номер функции в регистр C. См. описание функций в [[#n10|разделе 10]]. {{anchor:n92}} ===== 9.2. Обмен данными между NestorBASIC и NestorMan ===== При использовании [[msx:nestorman:|]] из NestorBASIC, обычно Вам придётся осуществлять передачу данных между сегментом NestorBASIC и сегментом [[msx:nestorman:|]]. Есть три способа сделать это: - Если сегмент источника или назначения — это сегмент TPA (номер сегмента от 0 до 3), достаточно использовать соответствующую функцию [[msx:nestorman:|]] для передачи блока данных ([[#f14|функция 14]]), поскольку [[msx:nestorman:|]] и так видит эти сегменты. - Можно использовать сегмент 4 NestorBASIC как промежуточный буфер для пересылки. Например, предположим пересылку из NestorBASIC в [[msx:nestorman:|]]. S1 это источник — сегмент NestorBASIC, S2 это назначение — сегмент [[msx:nestorman:|]], и S3 это номер сегмента [[msx:nestorman:|]], соответствующий 4 сегменту NestorBASIC. Тогда, сначала делается пересылка S1→4 с помощью функции NestorBASIC ([[#f10|функция 10]]), и затем делается пересылка S3→S2 с использованием функции [[msx:nestorman:|]] ([[#f14|функция 14]]). - Функции [[#f83|83]] и [[#f84|84]] NestorBASIC осуществляют блочное копирование данных из сегмента [[msx:nestorman:|]] в сегмент NestorBASIC и наоборот. Чтобы прочитать или записать единственный байт данных из/в сегмент [[msx:nestorman:|]], проще всего использовать соответствующие функции, которые предоставляет [[msx:nestorman:|]] (функции [[#f12|12]] и [[#f13|13]]). Помните, что некоторые функции NestorBASIC используют сегмент 4 как служебный буфер для временного размещения данных. См. [[#n10|раздел 10]] или [[#a1|приложение 1]], чтобы узнать эти функции. {{anchor:n93}} ===== 9.3. Использование InterNestor Suite ===== Методика, при использовании [[msx:internestor_suite:|]] из NestorBASIC, схожа с той, что применяется для работы с [[msx:nestorman:|]]. Единственно, нужно иметь в виду следующее: * [[#f85|Функция 85]] позволяет исполнять процедуры [[msx:internestor_suite:|]]. * Чтобы читать и записывать данные в сегменты [[msx:internestor_suite:|]] (константы конфигурации и переменные), сначала нужно, используя [[#f81|функцию 81]], выяснить номера сегментов модулей [[msx:internestor_suite:|]] (каждый модуль занимает сегмент [[msx:nestorman:|]]), а далее, использовать методы обмена данными, описанные в предыдущем разделе. * Процедуры [[msx:internestor_suite:|]] для чтения/записи данных TCP или датаграмм UDP допускают использование только сегментов TPA как источника/назначения данных или датаграмм. Для этой цели можно использовать последнюю часть сегмента NestorBASIC (сегмент 0) как временный буфер. Это свободное пространство всегда будет, как минимум, размером 600 байт, независимо от используемой версии NestorBASIC. \\ Этого достаточно для размещения стандартной датаграммы до 576 байт длинной (или для размещения блока данных TCP до 600 байт включительно). Пример программы ''TCPCON-S.BAS'' (см. [[#tcpcon|здесь]]), поставляемый с NestorBASIC, иллюстрирует использование NestorBASIC'а совместно с [[msx:internestor_suite:|]]. ВНИМАНИЕ: [[msx:internestor_suite:|]] это устаревшее ПО и не рекомендуется к спользованию. Если Вам нужен рабочий стэк TCP/IP, посмотрите в сторону [[msx:internestor_lite:|]]. {{anchor:n94}} ===== 9.4. Использование InterNestor Lite ===== [[msx:internestor_lite:|]] это гораздо более простая программа, чем [[msx:internestor_suite:|]], поэтому использовать её из NestorBASIC также проще. Предоставляется единственная функция ([[#f86|функция 86]]), которая позволяет выполнять несколько процедур из сегмента кода [[msx:internestor_lite:|]]. Чтобы читать или писать в его сегмент данных, необходимо использовать процедуры ''GET_VAR'', ''SET_VAR'' и ''COPY_DATA'', которые находятся в сегменте кода. Чтобы узнать, запущен [[msx:internestor_lite:|]] или нет, используйте [[#f58|функцию 58]] для вызова хука ''EXTBIO'' (адрес &HFFCA), передав A=0 и DE=&H2203. Если подпрограмма вернула A≠0, значит [[msx:internestor_lite:|]] запущен. Больше подробностей в описании [[#f86|функции 86]]. Многие из процедур [[msx:internestor_lite:|]] используют адреса TPA как источник либо назначение для обмена данными с приложениями. Для таких процедур можно указать адреса выше &H8000, которые соответствуют основной памяти [[msx:basic:]] и рабочей области системы; или адреса ниже &H4000, которые соответствуют сегменту NestorBASIC (сегмент 0). В конце сегмента NestorBASIC есть свободная область, размер которой варьируется, в зависимости от версии NestorBASIC, но никогда не бывает меньше, чем 600 байт. Эта область может быть использована как временный буфер для обмена данными с [[msx:internestor_lite:|]]. Другими словами, можно использовать диапазон от H3DA8 до &H3FFF в качестве TPA области — источника или приёмника для обмена данными между NestorBASIC и [[msx:internestor_lite:|]]. Пример программы ''TCPCON-L.BAS'' (см. [[#tcpcon|здесь]]), поставляемый с NestorBASIC, иллюстрирует использование NestorBASIC совместно с [[msx:internestor_suite:|]]. {{anchor:n95}} ===== 9.5. Ошибки ===== [[#f86|Функция 86]] (вызов процедуры [[msx:internestor_lite:|]]) возвращает ошибку -1, если [[msx:internestor_lite:|]] не обнаружен. [[#f85|Функция 85]] (вызов процедуры [[msx:internestor_suite:|]]) возвращает ошибку -1, если [[msx:internestor_suite:|]] не обнаружен, или если в P(0) указан недействительный номер модуля (действительны номера с 1 по 4). Функции [[#f83|83]] и [[#f84|84]] (передача блоков данных между сегментом [[msx:nestorman:|]] и сегментом NestorBASIC) выдаёт ошибку -1, если задан несуществующий сегмент [[msx:nestorman:|]] или NestorBASIC. Эти функции могут использовать сегменты VRAM и 255-й сегмент. Функции [[#f80|80]], [[#f81|81]] и [[#f82|82]] никогда не выдают ошибок. {{anchor:n96}} ===== 9.6. Функции для запуска программ на BASIC ===== {{anchor:f55}} ==== Функция 55 ==== Запуск программы на BASIC, находящейся в сегменте (S4) |<50% 10% 20% 70%>| ^Вход|P(0)|Сегмент| ^:::|P(1)|Начальный адрес| | ||| ^Выход| — || ВАЖНО: Чтобы использовать эту функцию нужно изменить начальный адрес BASIC–программ. Детально об этом — в [[#n6|разделе 6]]. Эта функция запускает программу на BASIC, расположенную в указанном сегменте. Программа должна находиться, начиная с адреса, указанного в P(1), в сегменте номер P(0), в следующем формате: |+&H0000:|Не используется NestorBASIC. Может быть полезно, например, в качестве байта-идентификатора.| |+&H0001:|Адрес конца программы +1, в диапазоне &H8000-&HBFFF; младший байт.| |+&H0002:|То же, старший байт.| |+&H0003:|Начало программы.| Все существующие числовые переменные вызывающей BASIC–программы будут переданы в вызываемую программу. Вы можете использовать данную функцию внутри турбо–блока, но в таком случае будут переданы только те целочисленные переменные, которые были объявлены вне турбо–блока и переданы в него посредством CALL TURBO ON (переменная, ..., массив(), ...) Строковые переменные, хранящиеся в строковой области переменных [[msx:basic:|]] будут также перенесены, но строки, определённые непосредственно в тексте программы, хранятся внутри самого текста программы на BASIC, и не будут переданы. Чтобы гарантированно удостовериться, что строка хранится в области строковых переменных BASIC, выполните следующую операцию: C$=C$+"" Конечно, самым практичным способом было бы сосредоточить все строковые переменные в строковый массив (например, F$), и проделать эту операцию в простом цикле. Эта функция выдаст ошибку -1, если указан несуществующий сегмент или 255-й. Ошибка -2 будет выдана, если основной памяти [[msx:basic:|]] не достаточно, чтобы вместить вызываемую программу и существующие переменные вызывающей программы. Такая ситуация может возникнуть, если новая (вызываемая) программа больше, чем вызывающая программа. Но если разница в размерах не очень велика, и переменных не слишком много, вы не должны оказаться в этой ситуации. {{anchor:f55}} ==== Функция 56 ==== Актуализация программы на BASIC, находящейся в сегменте (S4) |<50% 10% 20% 70%>| ^Вход|P(0)|Сегмент| ^:::|P(1)|Начальный адрес| | ||| ^Выход| — || ВАЖНО: Чтобы использовать эту функцию нужно изменить начальный адрес BASIC–программ. Детально об этом — в [[#n6|разделе 6]]. Эта функция работает так же, как [[#f55|функция 55]], с единственным отличием: после того, как новая программа помещена в основное ОЗУ [[msx:basic:|]], и переменные размещены после неё — программа не выполняется, а интерпретатор BASIC возвращается в командный режим. За исключением этого — функционал тот же, как и причины и коды ошибок. {{anchor:f57}} ==== Функция 57 ==== Сохранить программу на BASIC со специальным заголовком (S4) |<50% 10% 20% 70%>| ^Вход|P(0)|Байт, который будет сохранен в первой позиции заголовка \\ (Не используется NestorBASIC)| ^:::|F$(0)|Путь + имя файла| ^:::|P(1)|Начальный адрес| | ||| ^Выход|P(1)| * -1 — Нет ошибок * <> -1 — Произошла дисковая ошибка, и файл остался открытым под данным номером; команда ''USR'' в таком случае возвращает код ошибки, как и положено. | ВАЖНО: Чтобы использовать эту функцию нужно изменить начальный адрес BASIC–программ. Детально об этом — в [[#n6|разделе 6]]. Данная функция сохраняет активную BASIC–программу в указанный файл, с соответствующим заголовком, чтобы запускаться или активироваться с помощью функций [[#f55|55]] или [[#f56|56]] (см. [[#f55|функцию 55]] для подробностей о формате заголовка). Эта функция облегчает конвертацию обычных программ на BASIC в программы, исполняемые функцией 55; эта конвертация, таким образом, упрощается до следующего: load"prog.bas" 'Загрузка программы на BASIC F$(0)="prog.nba":?USR(57) 'Сохранение программы на BASIC с заголовком 'Задавать P(0) не обязательно Сохранённая таким образом, программа загружается и запускается просто: 1000 'Открыть prog.nba, прочитать в сегмент S и закрыть 1001 F$(0)="prog.nba":?USR(31):P(2)=S:P(3)=0:P(4)=&H4000:?USR(33):?USR(32) ... 10000 'Запуск программы (обработка ошибок не обязательна) 10001 P(0)=S:P(1)=0:IF USR(55)=-1 THEN PRINT "ОШИБКА: Несуществующий сегмент!" ELSE PRINT "ОШИБКА: Не достаточно памяти!" 10002 END Используя [[#f56|функцию 56]] вместо [[#f55|функции 55]], вы можете загружать программы, сохранённые с заголовком, для которых не имеется копий в обычном формате (LOADable). Конечно же, вы можете также использовать обычные функции доступа к диску для сохранения программ, но тогда вам придётся создать заголовок вручную: POKE &H8000,P(0) 'Байт не используемый NestorBASIC POKE &H8001,PEEK(&HF6C2) POKE &H8002,PEEK(&HF6C3) 'Сохранить начиная с &H8000 по PEEK(&H8001)+256*PEEK(&H8002) в файл Коды ошибок, возвращаемые этой функцией — такие же, как у функций доступа к диску (см. [[#n4|раздел 4]]). Если дисковая ошибка повлекла за собой то, что файл остался открытым, тогда в P(1) будет содержаться соответствующий номер файла. В противном случае, в P(1) будет -1. {{anchor:n10}} ====== 10. Функции NestorBASIC ====== {{anchor:n101}} ===== 10.1. Общее описание ===== Функции, которые составляют NestorBASIC, обозначаются числом, которое задаётся в качестве операнда команды ''USR''. Таким образом, чтобы использовать функцию номер F, Вам нужно просто выполнить ''USR(F)'', имея в виду, что если F — это переменная, то она должна быть целочисленного типа. Параметры для функций должны быть установлены в массиве P (и, в некоторых случаях, в массиве F$) перед вызовом функции. После выполнения, результаты функции записываются в те же массивы, P и/или F. Элементы массивов P и F$, которые не упоминаются явно в списках результатов каждой функции, возвращаются неизмененными, за исключением адресов в сегменте — они приводятся к диапазону &H0000-&H3FFF (кроме адресов сегмента 255, которые никогда не конвертируются). Если функция возвращает ошибку, выходные параметры будут недействительными (P и F$ остаются неизменны), если иное не сказано в описании функции. «Блок VRAM» соотносится либо с 64кБ нижней VRAM (блок 0), либо с 64кБ верхней VRAM (блок 1). Адреса VRAM имеют диапазон &H0000-&HFFFF. Если адрес VRAM переходит из &HFFFF в &H0000 путём автоинкремента, блок VRAM также изменяется (c 0 на 1, или с 1 на 0). Команда ''USR'' возвращает код ошибки, или 0, если ошибок не возникло. Коды ошибок, характерные для каждой группы функций, объяснены в соответствующих разделах. [[#a1|Приложение 1]] содержит полный список функций, который может быть полезен в качестве краткого справочника. {{anchor:n102}} ===== 10.2. Общие функции ===== {{anchor:f0}} ==== Функция 0 ==== Выгрузка NestorBASIC'а из памяти (S4) |<100% 10% 15% 75%>| ^Вход|P(0) = 0|Не освобождать область основной памяти [[msx:basic:|]], зарезервированную NestorBASIC| ^:::|P(0) ≠ 0|Освободить область основной памяти [[msx:basic:|]], зарезервированную NestorBASIC| | ||| ^Выход| — || Эта функция выгружает NestorBASIC: высвобождает ''USR'' и, в случае [[msx:dos2:|]], освобождает все выделенные сегменты. Также, останавливаются все процессы, завязанные на прерывания (прерывания, определяемые пользователем, проигрывание звуковых эффектов PSG и музыки). Всегда следует выгружать NestorBASIC прежде чем вернуться в [[msx:dos:|]]; в противном случае, все зарезервированные сегменты ОЗУ не будут высвобождены, и, следовательно, не смогут быть использованы до перезагрузки компьютера. Перед тем как выгрузить NestorBASIC, убедитесь, что не оставили открытых файлов. В противном случае, если в них осуществлялась какая-то запись, во внутренних буферах [[msx:dos:|]] могут оставаться несохраненные данные, которые будут потеряны. Вдобавок, в случае с [[msx:dos2:|]], не высвобождаются дескрипторы открытых файлов (file handles). Если функции передано P(0)=0, то область основной памяти [[msx:basic:|]], занятая обработчиком вызовов NestorBASIC (примерно 500 байт) не освобождается, что оставляет в силе схему распределения памяти, заданную командами ''CLEAR'' после загрузки NestorBASIC. Если функции передано P(0)≠0, схема распределения ОЗУ возвращается к параметрам, установленным до загрузки NestorBASIC. То есть, ''FRE(0)'' возвращает такое же значение, как до загрузки NestorBASIC. Учтите, что переменные в этом случае инициализируются. Эта функция никогда не выдаёт ошибки. {{anchor:f1}} ==== Функция 1 ==== Получение общей информации о NestorBASIC и конкретном логическом сегменте. |<100% 5% 5% 90%>| ^ Вход | P(0) | Номер исследуемого сегмента | | ||| ^ Выход | P(0) | Число доступных сегментов ОЗУ | | ::: | P(1) | мажорная версия NestorBASIC | | ::: | P(2) | минорная версия NestorBASIC, в формате BCD (должна показываться в шестнадцатеричном формате) | | ::: | P(3) | Мажорная версия [[msx:dos:|]] | | ::: | P(4) | Минорная версия [[msx:dos:|]], в формате BCD (должна показываться в шестнадцатеричном формате) | | ::: | P(5) | Размер области памяти в основном ОЗУ [[msx:basic:|]], занятой обработчиком USR-вызовов NestorBASIC | | ::: | P(6) | Объем VRAM в кБ (64 или 128) | | ::: | P(7) | Адрес начала свободной области в сегменте 0 (&H3DA8 как максимум) | | ::: | P(8) | Номер последней вызванной функции | | ::: | P(9) | Число открытых файлов | | ::: | P(10) | Максимальное количество одновременно открытых файлов (действительно только под [[msx:dos:|]]) | | ::: | P(11) | Слот, которому принадлежит логический сегмент, указанный в P(0) (255, если сегмент не существует, или является сегментом VRAM) | | ::: | P(12) | Номер физического сегмента, соответствующего логическому сегменту, указанному в P(0) | | ::: | F$(0) | Полный путь к файлу NBASIC.BIN | Под DOS 2, максимальное количество одновременно открытых файлов зависит от состояния внутренней памяти [[msx:dos:|DOS]], но не может превышать 63. Эта функция возвращает ошибку -1 если заданный в P(0) логический сегмент не существует, является сегментом VRAM или 255-м сегментом. Как бы то ни было, даже в этом случае результаты в элементах с P(0) по P(10) будут действительными. Число, возвращаемое в P(0) этой функцией будет таким же, как число, возвращаемое в P(0) функцией 80; а конкретно — это количество сегментов, зарезервированных для NestorBASIC. По-умолчанию (если функция 80 ещё не вызывалась после загрузки NestorBASIC), NestorBASIC резервирует для себя все свободные сегменты ОЗУ (до 247) во время своей загрузки. Под [[msx:dos:|]], F$(0) будет содержать только букву диска и двоеточие (например ''A:''), а под [[msx:dos2:|]] — имя диска и каталога, заканчивающиеся «\» (например ''C:\UTILS\AMAZING\''). Адрес, возвращаемый в P(7) зависит от версии NestorBASIC, но всегда будет меньше или равен &H3DA8; то есть, как минимум 600 байт в конце сегмента NestorBASIC всегда будет доступно. Эта область может быть использована, например, как буфер для данных TCP или UDP-датаграмм при использовании [[msx:internestor_suite:|]] с NestorBASIC. ВНИМАНИЕ: Из-за бага в NestorBASIC'е, в P(7) возвращается &H7C60, то есть адрес из страницы 1. Тем не менее, он может быть использован в функциях NestorBASIC'а, так как в них он будет приведен к диапазону &H0000–&H4000, как и другие адреса. В P(8) содержится номер последней вызванной функции, не считая саму 1 функцию. Так что если были последовательно вызваны, например, функции 64, 3, 10, 1, 1, 1, в конечном счёте Вы получите ''P(8)=10''. Значение ноль будет означать, что ни одной функции, помимо 1-й, не выполнялось с момента загрузки NestorBASIC. {{anchor:n103}} ===== 10.3. Функции для доступа к логическим сегментам ===== {{anchor:f2}} ==== Функция 2 ==== Прочесть байт из сегмента |<50% 10% 10% 80%>| ^Вход|P(0)|Сегмент| ^:::|P(1)|Адрес| | ||| ^Выход|P(2)|Полученный байт| {{anchor:f3}} ==== Функция 3 ==== Прочесть байт из сегмента с автоинкрементом адреса |<50% 10% 10% 80%>| ^Вход|P(0)|Сегмент| ^:::|P(1)|Адрес| | ||| ^Выход|P(2)|Полученный байт \\ P(1) = P(1) + 1| {{anchor:f4}} ==== Функция 4 ==== Прочесть целое число (2 байта) из сегмента |<50% 10% 10% 80%>| ^Вход|P(0)|Сегмент| ^:::|P(1) = Адрес | ||| ^Выход|P(2)|Полученное целое число| Младший байт берётся из адреса P(1), а старший байт из адреса P(1)+1. {{anchor:f5}} ==== Функция 5 ==== Прочесть целое число (2 байта) из сегмента с автоинкрементом адреса |<50% 10% 10% 80%>| ^Вход|P(0)|Сегмент| ^:::|P(1)|Адрес| | ||| ^Выход|P(2)|Полученное целое число \\ P(1) = P(1) + 2| Младший байт берётся из адреса P(1), а старший байт из адреса P(1)+1. {{anchor:f6}} ==== Функция 6 ==== Записать байт в сегмент |<50% 10% 10% 80%>| ^Вход|P(0)|Сегмент| ^:::|P(1)|Адрес| ^:::|P(2)|Записываемый байт| | ||| ^Выход| — || {{anchor:f7}} ==== Функция 7 ==== Записать байт в сегмент с автоинкрементом адреса |<50% 10% 10% 80%>| ^Вход|P(0)|Сегмент| ^:::|P(1)|Адрес| ^:::|P(2)|Записываемый байт| | ||| ^Выход|P(1) = P(1) + 1|| {{anchor:f8}} ==== Функция 8 ==== Записать целое число (2 байта) в сегмент |<50% 10% 10% 80%>| ^Вход|P(0)|Сегмент| ^:::|P(1)|Адрес| ^:::|P(2)|Записываемое целое число| | ||| ^Выход| — || Младший байт записывается в адрес P(1), а старший байт в адрес P(1)+1. {{anchor:f9}} ==== Функция 9 ==== Записать целое число (2 байта) в сегмент с автоинкрементом адреса |<50% 10% 10% 80%>| ^Вход|P(0)|Сегмент| ^:::|P(1)|Адрес| ^:::|P(2)|Записываемое целое число| | ||| ^Выход|P(1) = P(1) + 2|| Младший байт записывается в адрес P(1), а старший байт в адрес P(1)+1. {{anchor:f10}} ==== Функция 10 ==== Блочная пересылка данных между сегментами |<50% 10% 10% 80%>| ^Вход|P(0)|Сегмент источника| ^:::|P(1)|Адрес начала источника| ^:::|P(2)|Сегмент назначения| ^:::|P(3)|Адрес начала назначения| ^:::|P(4)|Длина блока| ^:::|P(5)<> 0 -> Увеличить P(1)|| ^:::|P(6)<> 0 -> Увеличить P(3)|| ^Выход|P(1) = P(1) + P(4), если P(5)<>0|| ^:::|P(3) = P(3) + P(4), если P(6)<>0|| P(3)+P(4) должно быть меньше &H4000, иначе результат непредсказуем. {{anchor:f11}} ==== Функция 11 ==== Заполнить область ОЗУ байтом |<50% 10% 10% 80%>| ^Вход|P(0)|Сегмент| ^:::|P(1)|Начальный адрес| ^:::|P(2)|Байт| ^:::|P(3)|Длина области| | ||| ^Выход| — || P(3)+P(4) должно быть меньше &H4000, иначе результат непредсказуем. {{anchor:f12}} ==== Функция 12 ==== Заполнить область ОЗУ байтом с автоинкрементом адреса. |<50% 10% 10% 80%>| ^Вход|P(0)|Сегмент| ^:::|P(1)|Начальный адрес| ^:::|P(2)|Байт| ^:::|P(3)|Длина области| | ||| ^Выход|P(1) = P(1) + P(3)|| P(3)+P(4) должно быть меньше &H4000, иначе результат непредсказуем. {{anchor:n104}} ===== 10.4. Функции доступа к VRAM ===== {{anchor:f13}} ==== Функция 13 ==== Прочесть байт из VRAM |<50% 10% 10% 80%>| ^Вход|P(0)|Блок VRAM| ^:::|P(1)|Адрес| | ||| ^Выход|P(2)|Полученный байт| {{anchor:f14}} ==== Функция 14 ==== Прочесть байт из VRAM с автоинкрементом адреса |<50% 10% 10% 80%>| ^Вход|P(0)|Блок VRAM| ^:::|P(1)|Адрес| | ||| ^Выход|P(2)|Полученный байт \\ P(0):P(1) = P(0):P(1) + 1| {{anchor:f15}} ==== Функция 15 ==== Прочесть целое число (2 байта) из VRAM |<50% 10% 10% 80%>| ^Вход|P(0)|Блок VRAM| ^:::|P(1)|Адрес| | ||| ^Выход|P(2)|Полученный байт| Младший байт берётся из адреса P(1), а старший байт из адреса P(1)+1. {{anchor:f16}} ==== Функция 16 ==== Прочесть целое число (2 байта) из VRAM с автоинкрементом адреса |<50% 10% 10% 80%>| ^Вход|P(0)|Блок VRAM| ^:::|P(1)|Адрес| | ||| ^Выход|P(2)|Полученное целое число \\ P(0):P(1) = P(0):P(1) + 2| Младший байт берётся из адреса P(1), а старший байт из адреса P(1)+1. {{anchor:f17}} ==== Функция 17 ==== Записать байт в VRAM |<50% 10% 10% 80%>| ^Вход|P(0)|Блок VRAM| ^:::|P(1)|Адрес| ^:::|P(2)|Записываемый байт| | ||| ^Выход| — || {{anchor:f18}} ==== Функция 18 ==== Записать байт в VRAM с автоинкрементом адреса |<60% 5% 5% 90%>| ^Вход|P(0)|Блок VRAM| ^:::|P(1)|Адрес| ^:::|P(2)|Записываемый байт| | ||| ^Выход|P(0):P(1) = P(0):P(1) + 1|| {{anchor:f19}} ==== Функция 19 ==== Записать целое число (2 байта) в VRAM |<50% 10% 10% 80%>| ^Вход|P(0)|Блок VRAM| ^:::|P(1)|Адрес| ^:::|P(2)|Записываемое целое число| | ||| ^Выход| — || Младший байт записывается в адрес P(1), а старший байт в адрес P(1)+1. {{anchor:f20}} ==== Функция 20 ==== Записать целое число (2 байта) в VRAM с автоинкрементом адреса |<50% 10% 10% 80%>| ^Вход|P(0)|Блок VRAM| ^:::|P(1)|Адрес| ^:::|P(2)|Записываемое целое число| | ||| ^Выход|P(0):P(1) = P(0):P(1) + 2|| Младший байт записывается в адрес P(1), а старший байт в адрес P(1)+1. {{anchor:f21}} ==== Функция 21 ==== Блочная пересылка данных из VRAM в RAM |<50% 10% 10% 80%>| ^Вход|P(0)|Блок VRAM источника| ^:::|P(1)|Начальный адрес источника (VRAM)| ^:::|P(2)|Сегмент назначения| ^:::|P(3)|Начальный адрес назначения (RAM)| ^:::|P(4)|Количество пересылаемых байт| ^:::|P(5)<> 0 -> Увеличить P(1)|| ^:::|P(6)<> 0 -> Увеличить P(3)|| | ||| ^Выход|P(1) = P(1) + P(4), если P(5)<>0|| ^:::|P(2):P(3) = P(2):P(3) + P(4), если P(6)<>0|| P(3)+P(4) должно быть меньше &H4000, иначе результат непредсказуем. {{anchor:f22}} ==== Функция 22 ==== Пакетная пересылка данных из RAM в VRAM |<50% 10% 10% 80%>| ^Вход|P(0)|Сегмент источника| ^:::|P(1)|Начальный адрес источника (RAM)| ^:::|P(2)|Блок VRAM назначения| ^:::|P(3)|Начальный адрес назначения (VRAM)| ^:::|P(4)|Количество пересылаемых байт| ^:::|P(5)<> 0 -> Увеличить P(1)|| ^:::|P(6)<> 0 -> Увеличить P(3)|| | ||| ^Выход:|P(1) = P(1) + P(4), если P(5)<>0|| ^:::|P(2):P(3) = P(2):P(3) + P(4), если P(6)<>0|| {{anchor:f23}} ==== Функция 23 ==== Пакетная пересылка данных в пределах VRAM |<50% 10% 10% 80%>| ^ Вход | P(0) | Блок VRAM источника | | ::: | P(1) | Начальный адрес источника | | ::: | P(2) | Блок VRAM назначения | | ::: | P(3) | Начальный адрес назначения | | ::: | P(4) | Количество пересылаемых байт (максимум &H4000) | | ::: | P(5)<> 0 -> Увеличить P(1) || | ::: | P(6)<> 0 -> Увеличить P(3) || | ||| ^ Выход | P(0):P(1) = P(0):P(1) + P(4), если P(5)<>0 || | ::: | P(2):P(3) = P(2):P(3) + P(4), если P(6)<>0 || Если P(4) больше &H4000, только &H4000 байт будет переслано, и инкремент адреса тоже будет ограничен &H4000, но P(4) не будет модифицирован. Таким образом, для пересылки больших блоков (до 64Кб) простым способом Вы можете выполнить примерно следующее: 10 'P(0) to P(3) already set. Data block length set in L. 20 P(5)=1:P(6)=1 30 P(4)=VAL("&H"+HEX$(L)):J=USR(23):L=L-&H4000:IF L>0 THEN 30 Преобразование L из десятичного в шестнадцатиричный формат, а потом обратно — требуется из-за того, что целочисленные переменные в [[msx:basic:|]] имеют диапазон значений от -32768 до 32767; если большее значение непосредственно занести в P(4), случится ошибка переполнения. Так как [[msx:x-basic:|]] работает с вещественными переменными особым способом, то, если применять этот приём внутри турбо-блока, L должно быть целым, кратным 256. {{anchor:f24}} ==== Функция 24 ==== Заполнить область VRAM байтом |<50% 10% 10% 80%>| ^Вход|P(0)|Блок VRAM| ^:::|P(1)|Начальный адрес| ^:::|P(2)|Записываемый байт| ^:::|P(3)|Длина области (максимум 16кБ)| | ||| ^Выход| — || Чтобы заполнить область, размером больше 16кБ, используйте метод, описанный в [[#f23|функции 23]]. {{anchor:f25}} ==== Функция 25 ==== Заполнить область VRAM байтом с автоинкрементом адреса |<50% 10% 10% 80%>| ^Вход|P(0)|Блок VRAM| ^:::|P(1)|Начальный адрес| ^:::|P(2)|Записываемый байт| ^:::|P(3)|Длина области (максимум 16кБ)| | ||| ^Выход:|P(0):P(1) = P(0):P(1) + P(3)|| Чтобы заполнить область, размером больше 16кБ, используйте метод, описанный в [[#f23|функции 23]]. {{anchor:n105}} ===== 10.5. Функции для работы с диском ===== {{anchor:f26}} ==== Функция 26 ==== Поиск файла (S4) |<50% 10% 15% 75%>| ^Вход|F$(1)|Маска поиска (пустая строка="*.*")| ^:::|P(0) = 0| Поиск первого файла, соответствующего маске| ^:::|P(0) = 1|Поиск последующих файлов, соответствующих маске| ^:::|P(1)|Атрибуты поиска: 2*H + 4*S + 8*V + 16*D * H = 1 -> Включить скрытые файлы в поиск * S = 1 -> Включить системные файлы в поиск * V = 1 -> Искать только метку тома * D = 1 -> Включить подкаталоги в поиск | | ||| ^Выход|F$(0)|Имя найденного файла| ^:::|P(0) = 1|| ^:::|P(1)|Атрибуты файла (всегда 0 под [[msx:dos:|]]): \\ \\ R + 2*H + 4*S + 8*V + 16*D + 32*A * R = 1 -> Только для чтения * H = 1 -> Скрытый * S = 1 -> Системный * V = 1 -> Метка тома * D = 1 -> Директория * A = 1 -> Архивный | ^:::|P(2)|Час создания/последней модификации (0–23)| ^:::|P(3)|Минута создания/последней модификации (0–59)| ^:::|P(4)|День создания/последней модификации (1–31)| ^:::|P(5)|Месяц создания/последней модификации (1–12)| ^:::|P(6)|Год создания/последней модификации (1980–2079)| ^:::|P(7)|Первый кластер (2–4095)| ^:::|P(8)|Логический диск (0=A:,...,7=H:)| ^:::|P(9)|Длина файла (младшее слово)| ^:::|P(10)|Длина файла (старшее слово)| ^:::|P(11)| 0, если ничего не найдено при первоначальном поиске \\ 1, если при первоначальном поиске найден файл \\ P(11), если при дальнейшем поиске ничего не найдено \\ P(11)+1, если при дальнейшем поиске файл найден | F$(1) может включать букву диска и, в случае [[msx:dos2:|]], путь; F$(0) будет содержать только имя найденного файла. P(0) должен быть установлен в 0, чтобы искать первое встретившееся совпадение с заданной маской, и оставлен равным 1, чтобы искать следующие файлы. Это то, что функция делает автоматически (всегда устанавливает P(0) в 1). Кроме того, P(11) устанавливается в 1 при первоначальном поиске файла (0 если ничего не найдено), и инкрементируется автоматически на каждой последующей итерации. Поэтому, чтобы найти соответствующие маске файлы, можно использовать цикл вроде этого: 10 'Search of all the filenames in drive B: (default directory) 20 F$(1)="B:":P(0)=0:P(1)=2+16 'Include directories and hidden files 30 IF USR(26)<>0 THEN PRINT:PRINT"Total found:";P(11):END 40 PRINT F$(0),CHR$(-ASC("h")*((P(1)AND2)<>0)); CHR$(-ASC("d")*((P(1)AND16)<>0)); CHR$(-ASC("a")*((P(1)AND32)<>0)):GOTO 30 Если больше не осталось совпадающих с маской файлов/директорий, функция вернёт ошибку «Файл не найден». Под [[msx:dos:|]], ошибка при поиске первого файла может означать также, что диск не существует или имя файла задано некорректно (под [[msx:dos2:|]] эти ошибки имеют свой собственный код). Чтобы получить длину файла, можно использовать формулу P(9)+65536*P(10). При выводе на экран этих длин, помните, что представление числовых переменных различается в [[msx:basic:|]] и [[msx:x-basic:|]] для больших чисел; лучше всего отображать размер файлов сразу в килобайтах: INT(P(9)/1024)+64*P(10). {{anchor:f27}} ==== Функция 27 ==== Переименование файла (S4) |<50% 10% 10% 80%>| ^Вход|F$(0)|Имя файла| ^:::|F$(1)|Новое имя файла| | ||| |Выход| — || F$(0) может также включать имя диска и, в случае с [[msx:dos2:|]], путь; F$(1) должен содержать только новое имя файла. Под [[msx:dos:|]] можно переименовывать несколько файлов за один раз, используя маски; под [[msx:dos2:|]] можно переименовать только один файл за раз. {{anchor:f28}} ==== Функция 28 ==== Удаление файла |<50% 10% 10% 80%>| ^Вход|F$(0)|Имя файла| | ||| |Выход| — || F$(0) может также включать имя диска и, в случае с [[msx:dos2:|]], путь. Под [[msx:dos2:|]] эта функция выдаст ошибку, если Вы попытаетесь удалить открытый файл. Под [[msx:dos:|]] можно удалить открытые файлы, но это не рекомендуется, потому что последующие попытки доступа у этим файлам могут привести к непредсказуемым результатам. Под [[msx:dos:|]] можно удалять несколько файлов за один раз, используя маски; под [[msx:dos2:|]] можно удалить только один файл за раз. {{anchor:f29}} ==== Функция 29 ==== {{:msx:msxdos2-logo.svg?100&nolink|MSX-DOS 2}} Перемещение файла ([[msx:dos2:|]]) |<50% 10% 10% 80%>| ^Вход|F$(0)|Имя файла| ^:::|F$(1)|Новое расположение файла| | ||| ^Выход| — || Эта функция доступна только под [[msx:dos2:|]]. Под [[msx:dos:|]] всегда возвращает ошибку 1. F$(0) может также включать имя диска и путь. F$(1) не должен содержать ни имени файла (файл при перемещении сохраняет то же имя), ни буквы диска (файл может быть перемещен только в другой каталог на том же диске). Если задать каталог вместо файла в F$(0), все его подкаталоги и содержащиеся в нём файлы тоже будут перемещены. {{anchor:f30}} ==== Функция 30 ==== Создание файла или директории |<50% 10% 10% 80%>| ^Вход|F$(0)|Имя файла или директории| ^:::|P(0)|Атрибуты при создании (игнорируются под [[msx:dos:|]]): * R + 2*H + 4*S для файлов * 2*H + 16 для директорий * R = 1 — только для чтения * H = 1 — скрытый * S = 1 — системный | F$(0) может также включать имя диска и путь. Файл будет создан с нулевой длиной и не останется открытым: для доступа к файлу, его нужно будет предварительно явно открыть ([[#f31|функция 31]]). Под [[msx:dos:|]] можно создавать только файлы, и P(0) игнорируется. Под [[msx:dos2:|]] файлы всегда создаются с установленным атрибутом «архивный», в дополнение к атрибутам, заданным в P(0). {{anchor:f31}} ==== Функция 31 ==== Открытие файла |<50% 10% 10% 80%>| ^Вход|F$(0)|Имя файла| ^Выход|P(0)|Номер, назначенный файлу| F$(0) может содержать букву диска и, в случае с DOS 2, путь. Число, возвращаемое в P(0), идентифицирует файл, и будет указываться при последующих вызовах дисковых функций. Конкретное значение этого числа зависит от версии [[msx:dos:|]] и того, сколько файлов было открыто и закрыто ранее; не нужно воспринимать это значение как показатель текущего количества открытых файлов (используйте для этого [[#f1|функцию 1]]). Под [[msx:dos:|]], если превысить допустимое число одновременно открытых файлов, возникнет ошибка 3. Максимальное число одновременно открытых файлов под [[msx:dos:|]] можно узнать посредством [[#f1|1-й функции]]. {{anchor:f32}} ==== Функция 32 ==== Закрытие файла |<50% 10% 10% 80%>| ^Вход|P(0)|Номер файла| | ||| ^Выход| — || Очень важно закрывать файлы, которые уже не будут использоваться: иначе, если в них осуществлялась какая–то запись, во внутренних буферах [[msx:dos:|]] могут оставаться несохраненные данные, которые будут потеряны; к тому же, в этом случае, элемент каталога для этого файла не будет обновлён. {{anchor:f33}} ==== Функция 33 ==== Чтение из файла (S4) |<50% 10% 10% 80%>| ^ Вход | P(0) | Номер файла | | ::: | P(2) | Сегмент назначения | | ::: | P(3) | Начальный адрес назначения | | ::: | P(4) | Сколько байт прочитать | | ::: | P(6) | Увеличить P(3) если ≠0 | | ||| ^ Выход | P(7) | Число фактически прочитанных байт | | ::: | P(3) | P(3)+P(4), если P(6)≠0 | P(3)+P(4) должно быть меньше &H4000, иначе результат непредсказуем. Файл читается с позиции, на которую указывает файловый указатель; этот указатель автоматически увеличивается после чтения. Чтобы узнать или изменить этот указатель, используйте [[#f42|функцию 42]]. Чтобы прочитать файл до конца, или прочитать весь файл, если он короче 16кБ, проще всего попытаться прочесть 16кБ (установить P(4)=&H4000) и игнорировать ошибку с кодом 1 или 199: для данной функции, эти ошибки означают лишь то, что был достигнут конец файла. Если конец файла был достигнут до прочтения P(4) байт, будет выдана ошибка. Чтобы узнать число прочитанных байт, смотрите в P(7). Если нет ошибки, то в P(7) будет то же значение, что и в P(4); в случае физической ошибки (неисправная FAT, физическая ошибка диска или диск не вставлен), в P(7) всегда будет 0. {{anchor:f34}} ==== Функция 34 ==== Чтение из файла в VRAM (S4) |<50% 10% 10% 80%>| ^ Вход | P(0) | Номер файла | | ::: | P(2) | Блок VRAM назначения | | ::: | P(3) | Начальный адрес назначения | | ::: | P(4) | Сколько байт прочитать (максимум &H4000) | | ::: | P(6) | Увеличить P(3) если ≠0 | | ||| ^ Выход | P(7) | Число фактически прочитанных байт \\ P(2):P(3) = P(2):P(3)+P(4), если P(6)≠0 | Если P(4) больше &H4000, только &H4000 байт будет прочитано, и приращение адреса также будет ограничено &H4000, но P(4) не будет изменено. Поэтому, чтобы читать более крупные куски (до 64кБ), можно использовать приём, описанный в [[#f23|функции 23]]. Для этой функции также действительны замечания насчет файлового указателя и значения P(7), сделанные в описании функции 33. {{anchor:f35}} ==== Функция 35 ==== Чтение секторов диска (S4) |<50% 10% 10% 80%>| ^ Вход | P(0) | Привод (0=A:,...,7=H:) | | ::: | P(1) | Номер начального сектора | | ::: | P(2) | Сегмент назначения | | ::: | P(3) | Начальный адрес назначения | | ::: | P(4) | Сколько секторов прочитать (максимум 32) | | ::: | P(6) | Увеличить P(3) если ≠0 | | ||| ^ Выход | P(7) | P(4)*512 (0 в случае ошибки) | | ::: | P(3) | P(3)+P(4)*512, если P(6)≠0 | P(3)+P(4)×512 должно быть меньше &H4000, иначе результат непредсказуем. Эта функция не поддерживает частичное чтение: если не возникло ошибки, тогда P(7) будет содержать число прочитанных байт, то есть P(4)×512; но в случае ошибки в P(7) будет 0. Если P(6)≠0, P(3) будет увеличен на число прочитанных байт (P(7) или 0). {{anchor:f36}} ==== Функция 36 ==== Чтение секторов диска в VRAM (S4) |<50% 10% 10% 80%>| ^ Вход | P(0) | Привод (0=A:,…,7=H:) | | ::: | P(1) | Номер начального сектора | | ::: | P(2) | Блок VRAM назначения | | ::: | P(3) | Начальный адрес назначения | | ::: | P(4) | Сколько секторов прочитать (максимум 32) | | ::: | P(6) | Увеличить P(3) если ≠0 | | ||| ^ Выход | P(7) | P(4)×512 (0 в случае ошибки) | | ::: | P(3) | P(3)+P(4)×512, если P(6)≠0 | Если P(4) больше, чем 32 — только 32 сектора (&H4000 байт) будет прочитано, и приращение адреса также будет ограничено &H4000, но P(4) не будет изменено. Поэтому, чтобы читать более крупные куски (до 64кБ), можно использовать прием, описанный в [[#f23|функции 23]]. Для этой функции также действительны соображения относительно значения P(7), сделанные в описании [[#f35|функции 35]]. {{anchor:f37}} ==== Функция 37 ==== Запись в файл (S4) |<50% 10% 10% 80%>| ^ Вход | P(0) | Номер файла | | ::: | P(2) | Сегмент источника | | ::: | P(3) | Начальный адрес источника | | ::: | P(4) | Сколько байт записать | | ::: | P(6) | Увеличить P(3) если ≠0 | | ||| ^ Выход | P(7) | Число фактически записанных байт | | ::: | P(3) | P(3)+P(4), если P(6)≠0 | P(3)+P(4) должно быть меньше &H4000, иначе данные, записанные в файл, будут непредсказуемыми. Данные записываются в файл с позиции, на которую указывает файловый указатель; этот указатель автоматически увеличивается после чтения. Чтобы узнать или изменить этот указатель, используйте функцию 42. В случае физической ошибки (неисправная FAT, физическая ошибка диска или диск не вставлен), в P(7) всегда будет 0. {{anchor:f38}} ==== Функция 38 ==== Запись в файл из VRAM (S4) |<50% 10% 10% 80%>| ^ Вход | P(0) | Номер файла | | ::: | P(2) | Блок VRAM источника | | ::: | P(3) | Начальный адрес источника | | ::: | P(4) | Сколько байт записать (максимум &H4000) | | ::: | P(6) | Увеличить P(3) если ≠0 | | ||| ^ Выход | P(7) | Число фактически записанных байт | | ::: | P(2):P(3) | P(2):P(3)+P(4), если P(6)≠0 | Если P(4) больше &H4000, только &H4000 байт будет записано, и приращение адреса также будет ограничено &H4000, но P(4) не будет изменено. Поэтому, чтобы записывать более крупные куски (до 64кБ), можно использовать прием, описанный в [[#f23|функции 23]]. Для этой функции также справедливы замечания касательно файлового указателя, сделанные в описании [[#f37|функции 37]]. {{anchor:f39}} ==== Функция 39 ==== Запись в сектора диска (S4) |<50% 10% 10% 80%>| ^ Вход | P(0) | Привод (0=A:,...,7=H:) | | ::: | P(1) | Номер начального сектора | | ::: | P(2) | Сегмент источника | | ::: | P(3) | Начальный адрес источника | | ::: | P(4) | Сколько секторов записать (максимум 32) | | ::: | P(6) | Увеличить P(3) если ≠0 | | ||| ^ Выход | P(7) | P(4)*512 (0 в случае ошибки) | | ::: | P(3) | P(3)+P(4)×512, если P(6)≠0 | P(3)+P(4)×512 должно быть меньше &H4000, иначе данные, записанные в файл, будут непредсказуемыми. Эта функция не поддерживает частичную запись: если не возникло ошибки, тогда P(7) будет содержать число записанных байт, то есть P(4)×512; но в случае ошибки в P(7) будет 0. Если P(6)≠0, P(3) будет увеличен на число записанных байт (P(7) или 0). {{anchor:f40}} ==== Функция 40 ==== Запись в сектора диска из VRAM (S4) |<50% 10% 10% 80%>| ^ Вход | P(0) | Привод (0=A:,…,7=H:) | | ::: | P(1) | Номер начального сектора | | ::: | P(2) | Блок VRAM источника | | ::: | P(3) | Начальный адрес источника | | ::: | P(4) | Сколько секторов записать (максимум 32) | | ::: | P(6) | Увеличить P(3) если ≠0 | | ||| ^ Выход | P(7) | P(4)×512 (0 в случае ошибки) | | ::: | P(3) | P(3)+P(4)×512, если P(6)≠0 | Если P(4) больше, чем 32 — только 32 сектора (&H4000 байт) будет записано, и приращение адреса также будет ограничено &H4000, но P(4) не будет изменено. Поэтому, чтобы записывать более крупные куски (до 64кБ), можно использовать прием, описанный в [[#f23|функции 23]]. Для этой функции также справедливы замечания, касающиеся значения P(7), представленные в описании [[#f39|функции 39]]. {{anchor:f41}} ==== Функция 41 ==== Заполнение файла байтом (S4) |<50% 10% 10% 80%>| ^Вход|P(0)|Номер файла| ^:::|P(1)|Байт| ^:::|P(4)|Сколько байт записать (максимум &H4000)| | ||| ^Выход|P(7)|Число фактически записанных байт| Эта функция просто записывает P(4) байт, равных содержимому P(1), в сегмент 4, начиная с адреса 0, и затем вызывает функцию 37 с P(2)=4 и P(3)=0. Поэтому, все замечания, сделанные в [[#f37|функции 37]], будут также справедливы и здесь. {{anchor:f42}} ==== Функция 42 ==== Перемещение файлового указателя |<50% 10% 10% 80%>| ^Вход|P(0)|Номер файла| ^:::|P(1)|База для смещения: * 0 — Относительно начала файла * 1 — Относительно текущей позиции указателя * 2 — Относительно конца файла | ^:::|P(2)|Знаковое смещение (младшее слово)| ^:::|P(3)|Знаковое смещение (старшее слово)| | ||| ^Выход|P(4)|Новое положение файлового указателя (младшее слово)| ^:::|P(5)|Новое положение файлового указателя (старшее слово)| Чтобы установить в P(2) и P(3) смещение D большее, чем 32768 или меньшее, чем 0, нужно использовать следующую формулу: P(3)=INT(D/65536) P(2)=VAL("&H"+HEX$(D-(P(2)*65536))) а чтобы восстановить полученный новый указатель в переменную P, следующую: P=P(4)-(65536*(P(4)<0))+65536!*P(5) Так как [[msx:x-basic:|]] работает с вещественными переменными особым способом, то, если применять этот приём внутри турбо-блока, D должно быть целым, кратным 256. Чтобы узнать текущую позицию файлового указателя, просто используйте эту функцию с параметрами P(1)=1, P(2)=0 и P(3)=0; чтобы узнать длину файла, вызовите её с параметрами P(1)=2, P(2)=0 и P(3)=0. В первом случае указатель файла остаётся неизменным. При использовании данной функции, помните, что смещение интерпретируется со знаком. Поэтому: * Если Вы вызываете функцию с P(1)=0, смещение должно быть положительным. Иначе, при последующем доступе к файлу, результат будет непредсказуемым. * Если Вы вызываете функцию с P(1)=1, положительное смещение передвинет файловый указатель вперёд; отрицательное смещение передвинет файловый указатель назад. * Если Вы вызываете функцию с P(1)=2, смещение должно быть отрицательным; в противном случае, файловый указатель будет помещён после конца файла. В таком случае, дальнейшее чтение файла вызовет ошибку "End of file" (будет прочитано 0 байт), а запись в файл приведёт к тому, что пространство между концом файла и указателем будет заполнено нулями. {{anchor:f43}} ==== Функция 43 ==== Узнать текущий диск и вектор доступных дисков (login vector) |<50% 10% 10% 80%>| ^Вход| — || | ||| ^Выход|P(0)|Текущий диск (0=A:,...,7=H:)| ^:::|P(1)|Вектор доступных дисков| Вектор доступных дисков это байт, который содержит, в каждом бите, информацию о наличии или отсутствии (бит=1: присутствует, bit=0: отсутствует); младший бит соответствует диску A: а старший - диску H:. Например, если функция возвращает ''P(1)=&B01000011'', значит присутствуют диски A:, B: и G: {{anchor:f44}} ==== Функция 44 ==== Задать текущий диск |<50% 10% 10% 80%>| ^Вход|P(0)|Номер диска (0=A:,...,7=H:)| | ||| ^Выход| — || Эта функция выдаст ошибку 62 если попытаться установить текущим неверный диск (отсутствующий, или выше, чем 7). {{anchor:f45}} ==== Функция 45 ==== Информация о дисковом пространстве |<50% 10% 10% 80%>| ^Вход|P(0)|Привод (0=Текущий рабочий диск, 1=A:,...,8=H:)| | ||| ^Выход|P(1)|Секторов на кластер| ^:::|P(2)|Всего кластеров (максимум 4096)| ^:::|P(3)|Количество свободных кластеров| Свободное пространство в байтах можно вычислить по формуле P(1)*P(3)*512, или в килобайтах по формуле P(1)*P(3)/2; и то же самое с общим размером диска, используя P(2) вместо P(3). Эта функция выдаст ошибку 62 если попытаться получить информацию о неверном диске (отсутствующий, или выше, чем 8). {{anchor:f46}} ==== Функция 46 ==== {{:msx:msxdos2-logo.svg?100&nolink|MSX-DOS 2}} Узнать текущую директорию |<50% 10% 10% 80%>| ^Вход|P(0)|Привод (0=Текущий рабочий диск, 1=A:,...,8=H:)| | ||| ^Выход|F$(0)|Текущая рабочая директория| Эта функция доступна только под [[msx:dos2:|]]. Под [[msx:dos:|]] она будет всегда возвращать код ошибки 1. Полученная строка не содержит имени привода, а также "\" ни в начале, ни в конце; так, корневая директория будет представлена в виде пустой строки. {{anchor:f47}} ==== Функция 47 ==== {{:msx:msxdos2-logo.svg?100&nolink|MSX-DOS 2}} Задать текущую директорию |<50% 10% 10% 80%>| ^Вход|F$(0)|Привод (опционально) + директория| | ||| ^Выход| — || Эта функция доступна только под [[msx:dos2:|]]. Под [[msx:dos:|]] она будет всегда возвращать код ошибки 1. Эта функция не меняет текущий рабочий диск. Чтобы сделать это, используйте [[#f44|функцию 44]]. {{anchor:f48}} ==== Функция 48 ==== {{:msx:msxdos2-logo.svg?100&nolink|MSX-DOS 2}} Узнать размер RAM-диска |<50% 10% 10% 80%>| ^Вход| — || | ||| ^Выход|P(0)|размер RAM–диска в 16Кб сегментах| Эта функция доступна только под [[msx:dos2:|]]. Под [[msx:dos:|]] она будет всегда возвращать код ошибки 1. Чтобы получить размер RAM–диска в килобайтах, просто вычислите P(0)*16. Нулевой размер диска будет означать, что RAM–диск отсутствует. {{anchor:f49}} ==== Функция 49 ==== {{:msx:msxdos2-logo.svg?100&nolink|MSX-DOS 2}} Создать RAM–диск |<50% 10% 10% 80%>| ^Вход|P(0)|Размер (запрашиваемый) RAM-диска в 16Кб сегментах| | ||| ^Выход|P(0)|Размер созданного RAM-диска в 16Кб сегментах| Эта функция доступна только под [[msx:dos2:|]]. Под [[msx:dos:|]] она будет всегда возвращать код ошибки 1. Так как по-умолчанию NestorBASIC при первоначальном запуске выделяет себе все свободные сегменты, нужно вызвать функцию 80 для начала, чтобы уменьшить количество сегментов, выделенных NestorBASIC; в противном случае, не будет свободных сегментов для RAM–диска (если только в компьютере не больше 4Мб ОЗУ). Если нет P(0) свободных сегментов, но можно создать меньший по размеру RAM–диск, функция сделает это и не выдаст никакой ошибки; в P(0) будет возвращён размер созданного RAM–диска. Но если свободных сегментов не было вообще, и RAM–диск не был создан, тогда функция выдаст соответствующую ошибку. {{anchor:f50}} ==== Функция 50 ==== {{:msx:msxdos2-logo.svg?100&nolink|MSX-DOS 2}} Получить атрибуты файла |<50% 10% 10% 80%>| ^Вход|P(0)|Номер файла, или \\ P(0)=255, F$(0)=имя файла| | ||| ^Выход|P(1)|Байт атрибутов: * R + 2*H + 4*S + 8*V + 16*D + 32*A * R = 1 — только чтение * H = 1 — скрытый * S = 1 — системный * V = 1 — имя тома * D = 1 — директория * A = 1 — архивный | Эта функция доступна только под [[msx:dos2:|]]. Под [[msx:dos:|]] она будет всегда возвращать код ошибки 1. Если P(0)=255, будет прочитан байт атрибутов для файла с именем, указанным в F$(0). F$(0) может содержать букву имени привода и путь; Если нет, то будет прочитан байт атрибутов для уже открытого файла под номером P(0). {{anchor:f51}} ==== Функция 51 ==== {{:msx:msxdos2-logo.svg?100&nolink|MSX-DOS 2}} Установить атрибуты файла |<50% 10% 10% 80%>| ^Вход|P(0)|Номер файла, или \\ P(0) = 255 и F$(0) = имя файла| ^:::|P(1)|Байт атрибутов: * R + 2*H + 4*S + 8*V + 16*D + 32*A * R = 1 — только чтение * H = 1 — скрытый * S = 1 — системный * V = 1 — имя тома * D = 1 — директория * A = 1 — архивный | | ||| ^Выход|P(1)|Байт атрибутов, фактически присвоенных файлу| Эта функция доступна только под [[msx:dos2:|]]. Под [[msx:dos:|]] она будет всегда возвращать код ошибки 1. Если P(0)=255, то будет установлен байт атрибутов для файла с именем, заданным в F$(0). F$(0) может содержать букву имени привода и путь; Иначе, байт атрибутов будет установлен для уже открытого файла под номером P(0). Невозможно задать атрибуты уже открытого файла путём указания его имени в F$(0); если попытаться сделать это, произойдёт ошибка. Для открытого файла необходимо указывать его номер файла в P(0). Для файлов — могут быть модифицированы только атрибуты системный, скрытый, только чтение и архивный; Для директорий — только скрытый. Если вы попытаетесь изменить любой другой атрибут, вы получите ошибку. Нельзя изменить атрибуты "." и ".." элементов каталога. {{anchor:f52}} ==== Функция 52 ==== {{:msx:msxdos2-logo.svg?100&nolink|MSX-DOS 2}} Синтаксический разбор пути |<50% 10% 10% 80%>| ^Вход|F$(0)|Путь, для которого который нужно выполнить синтаксический разбор \\ P(10)<>0 если путь указывает на метку тома| | ||| ^Выход|F$(1)|Последний элемент пути| ^:::|P(8)|Номер логического привода (1=A:,...,8=H:)| ^:::|P(9)|Позиция последнего элемента в строке пути \\ (0 если последний элемент пути отсутствует)| ^:::|Нижеперечисленные переменные будут равны -1 при соблюдении данных условий, иначе они будут равны 0|| ^:::|P(0)|Путь содержит что-то помимо имени диска| ^:::|P(1)|В пути содержится название директории| ^:::|P(2)|В пути содержится имя диска| ^:::|P(3)|В пути содержится имя файла| ^:::|P(4)|Путь содержит расширение файла| ^:::|P(5)|Последний элемент пути не определён| ^:::|P(6)|Последний элемент пути "." или ".."| ^:::|P(7)|Последний элемент пути это ".."| Эта функция доступна только под [[msx:dos2:|]]. Под [[msx:dos:|]] она будет всегда возвращать код ошибки 1. Эта функция только обрабатывает входящую строку, возвращая соответствующие результаты. Не осуществляется никаких обращений к диску, не меняются текущие рабочий привод и директория. Если строка состоит из одной только лишь буквы привода, или если последним символом в строке является разделитель "\", это будет означать, что в строке нет "последнего элемента"; в этом случае, P(9) будет равняться 0 и F$(1) будет пустой строкой. __//Пример://__ \\ Для F$(0) = "A:\DIR\FILES\ONEFI.LE", "последним элементом", возвращаемым в F$(1), будет "ONEFI.LE", и P(9) будет равно 14. Если строка не содержит буквы привода, в P(2) будет возвращено текущее значение рабочего привода. Таким образом, P(2) никогда не будет равняться 0. Если на входе задано P(10)<>0, то P(1) и P(4) по P(7) всегда будут равны 0. {{anchor:n106}} ===== 10.6. Функции сжатия и распаковки графики ===== {{anchor:f53}} ==== Функция 53 ==== Сжатие графических данных |<50% 10% 20% 70%>| ^ Вход | P(0) | Блок VRAM источника | | ::: | P(1) | Начальный адрес источника (VRAM) | | ::: | P(2) | Первый сегмент назначения | | ::: | P(3) | Начальный адрес назначения (RAM) | | ::: | P(4) | Длинна сжимаемых VRAM данных | | ::: | P(5) <> 0 | Увеличить P(1) | | ::: | P(6) <> 0 | Увеличить P(3) | | ||| ^ Выход | P(7) | Полученный размер сжатых данных в RAM | | ::: | P(8) | Количество использованных сегментов RAM | | ::: | P(0):P(1) | P(0):P(1) + P(4), если P(5)<>0 | | ::: | P(2):P(3) | Адрес RAM, следующий за последним использованным, если P(6)<>0 | Компрессия осуществляется в последовательные сегменты: после записи сжатых данных по адресу &H3FFF сегмента S, запись продолжается с адреса &H0000 сегмента S+1. Если при этом сегмент S+1 не существует, то произойдёт ошибка 5. Эта функция не поддерживает сегменты VRAM и 255 сегмент. Если последним использованным RAM адресом был &H3FFF сегмента S, и было задано P(6)<>0, то в P(2) будет S+1 и в P(3) 0 по завершении. В этом случае, если S был последним доступным RAM–сегментом, по возвращении из функции в P(2) будет 0. {{anchor:f54}} ==== Функция 54 ==== Распаковка графических данных |<50% 10% 20% 70%>| ^ Вход | P(0) | VRAM-блок назначения | | ::: | P(1) | Начальный адрес назначения (VRAM) | | ::: | P(2) | Первый сегмент источника | | ::: | P(3) | Начальный адрес источника (RAM) | | ::: | P(5) <> 0 | Увеличить P(1) | | ::: | P(6) <> 0 | Увеличить P(3) | | ||| ^ Выход | P(7) | Полученный размер распакованного изображения в VRAM | | ::: | | | | ::: | P(0):P(1) | P(0):P(1) + P(7), если P(5)<>0 | | ::: | P(2):P(3) | Адрес RAM, следующий за последним использованным, если P(6)<>0 | Распаковка осуществляется в последовательные сегменты: после декомпрессии данных, находящихся по адресу &H3FFF в сегменте S, чтение исходных сжатых данных продолжается с адреса &H0000 сегмента S+1. Если при этом сегмент S+1 не существует, или обнаружена ошибка в сжатых данных, то произойдёт ошибка 6. Эта функция не поддерживает сегменты VRAM и 255 сегмент. Если последним использованным RAM адресом был &H3FFF сегмента S, и было задано P(6)<>0, то в P(2) будет S+1 и в P(3) 0 по завершении. В этом случае, если S был последним доступным RAM-сегментом, по возвращении из функции в P(2) будет 0. {{anchor:n107}} ===== 10.7. Другие различные функции ===== {{anchor:f58}} ==== Функция 58 ==== Выполнение подпрограммы в машинном коде, находящейся в [[msx:bios|BIOS]], [[msx:bios#subrom|SUB-BIOS]], основном ОЗУ [[msx:basic:|]] или [[msx:bios#work_area|системной рабочей области]] |<50% 10% 20% 70%>| ^Вход|P(0)|0 — чтобы выполнить подпрограмму в [[msx:bios|BIOS]], основном ОЗУ [[msx:basic:|]] или системной рабочей области <> 0 чтобы выполнить подпрограмму [[msx:bios#subrom|SUB-BIOS]] ^:::|P(1)|Адрес начала подпрограммы| ^:::|Регистры ЦП на входе в подпрограмму|| ^:::|P(2)|AF| ^:::|P(3)|BC| ^:::|P(4)|DE| ^:::|P(5)|HL| ^:::|P(6)|IX| ^:::|P(7)|IY| ^:::|P(8)|AF'| ^:::|P(9)|BC'| ^:::|P(10)|DE'| ^:::|P(11)|HL'| | ||| ^Выход|Регистры после возврата из подпрограммы, соответствие как у входящих, плюс следующие:|| ^:::|P(12)|A| ^:::|P(13)|Cy flag (-1 если установлен, 0 если нет)| ^:::|P(14)|Z flag (-1 если установлен, 0 если нет)| С помощью этой функции можно вызвать машинную подпрограмму, расположенную в [[msx:bios|BIOS]], [[msx:bios#subrom|SUB-BIOS]], основном ОЗУ [[msx:basic:|]] или системной рабочей области, задав предварительно входные значения регистров через массив P; после возвращения из подпрограммы, выходные значения регистров будут помещены в массив P, в таком же соответствии. Если на входе P(0)=0, данная функция напрямую запустит машинный код, находящийся по адресу, указанному в P(1), без каких–либо переключений слотов и сегментов. Практически это означает, что данным образом Вы можете вызывать процедуры BIOS (если их адрес находится в диапазоне 0–&H3FFF), программы, загруженные в основное ОЗУ Бейсика пользователем (например, командой BLOAD), и код, расположенный в рабочей области системы в странице 3 (например, хук расширенного BIOS, по адресу &HFFCA). Заметьте, однако, что при выполнении этой функции, сегмент NestorBASIC подключается в страницу 1. Из этого следует, что невозможно напрямую запустить код, находящийся в ПЗУ интерпретатора [[msx:basic:|]]. Чтобы вызвать процедуры ПЗУ [[msx:basic:|]], используйте BIOS–процедуру CALBAS (&H0159), которая принимает в IX адрес вызываемой подпрограммы интерпретатора BASIC. Если на входе P(0)<>0, то будет запущена подпрограмма из [[msx:bios#subrom|SUB-BIOS]], адрес которой указан в P(1); в этом случае, если указанный адрес больше, чем &H3FFF, будет возвращена ошибка с кодом -1. Для вызова подпрограмм [[msx:bios#subrom|SUB-BIOS]] используется BIOS–процедура EXTROM, так что входящее значение регистра IX [переменной P(6)] будет потеряно. Значение, возвращаемое в P(12), будет тем же самым, что и значение, возвращаемое в старшем байте P(2). Подобным же образом, значения, возвращаемые в P(13) и P(14) будут отражать состояние, соответственно, битов 0 и 6 младшего байта P(2). Так как обычно хотят получить именно значение регистра A, либо выходное состояние флагов Cy и Z, а не целой пары AF, то использование переменных с P(12) по P(14) представляется гораздо более удобным, чем использование P(2) при обработке результирующих значений регистров. Как бы то ни было, для установки входящих значений регистра A и флагов, необходимо использовать P(2), использование P(12)–P(14) не допускается. Вычислить значение, которое нужно занести в P(2), можно по следующей формуле: \\ P(2) = Cy + 2*N + 4*P/V + 16*H + 64*Z + 128*M + 256*A {{anchor:f59}} ==== Функция 59 ==== Выполнение подпрограммы пользователя (подпрограммы на машинном коде , размещённой в сегменте ОЗУ) |<50% 10% 20% 70%>| ^Вход|P(0)|Сегмент, в котором находится подпрограмма| ^:::|P(1)|Адрес начала подпрограммы| ^:::|Регистры ЦП на входе в подпрограмму|| ^:::|P(2)|AF| ^:::|P(3)|BC| ^:::|P(4)|DE| ^:::|P(5)|HL| ^:::|P(6)|IX| ^:::|P(7)|IY| ^:::|P(8)|AF'| ^:::|P(9)|BC'| ^:::|P(10)|DE'| ^:::|P(11)|HL'| | ||| ^Выход|P(2) по P(12)|Регистры после возврата из подпрограммы, соответствие как у входящих, плюс следующие:| ^:::|P(12)|A| ^:::|P(13)|Cy flag (-1 если установлен, 0 если нет)| ^:::|P(14)|Z flag (-1 если установлен, 0 если нет)| С помощью этой функции можно вызвать подпрограмму в кодах, размещённую в сегменте ОЗУ, с возможностью задать значения регистров ЦП перед вызовом, используя массив P; после возврата из подпрограммы, выходные значения регистров будут помещены в массив P, в том же соответствии. Указанный в P(0) сегмент будет подключён в страницу 2 для исполнения программы, поэтому она должна быть ассемблирована в диапазон адресов &H8000–&HBFFF. Перед выполнением подпрограммы, BIOS будет подключён в страницу 0, а сегмент NestorBASIC в страницу 1. Перед возвратом из пользовательской подпрограммы, это состояние должно быть восстановлено ей же самой, если осуществлялось какое-либо переключение слотов/сегментов. Некоторые из внутренних процедур и переменных NestorBASIC (для управления RAM и VRAM, и получения информации о прерываниях, среди прочего) могут использоваться пользовательскими подпрограммами в кодах. В [[#a2|приложении 2]] вы можете найти список и подробное описание этих процедур и переменных. Смотрите также описание [[#f58|функции 58]] по поводу замечаний относительно возвращаемых значений P(12)–P(14). Эта функция не поддерживает сегменты VRAM и 255 сегмент, и выдаст ошибку -1, если несуществующий сегмент указан в P(0). {{anchor:f60}} ==== Функция 60 ==== Вывести строку на дисплей в графическом режиме |<50% 10% 20% 70%>| ^Вход|F$(0)|Строка| | ||| ^Выход| — || Эта функция работает только в видеорежимах со SCREEN 5 по 11, и эквивалентна команде PRINT#1,F$(0) , предварённой командой OPEN"GRP:"AS#1 Разница в том, что данная функция совместима с [[msx:x-basic:|]]. При вызове в других видеорежимах, эта функция не будет делать ничего, но не выдаст никакой ошибки. Максимальная длина строки — 80 символов; если F$(0) больше, только первые 80 символов будут выведены. Строка не может содержать символа 0, потому что этот код интерпретируется как конец строки. {{anchor:f61}} ==== Функция 61 ==== Сохранить строку в сегмент |<50% 10% 20% 70%>| ^Вход|F$(0)|Строка| ^:::|P(0)|Сегмент| ^:::|P(1)|Начальный адрес| ^:::|P(2)|Увеличить P(1) если <>0| | ||| ^Выход|P(1)|P(1) + LEN(F$(0)) + 1, если P(2)<>0| Эта функция копирует строку F$(0) по заданному адресу указанного сегмента. Строка хранится с символом 0 в конце, поэтому будет занимать ''LEN(F$(0))''+1 байт. Максимальная длина строки — 80 символов; если F$(0) длиннее, только первые 80 символов будут скопированы. Строка не должна содержать 0, потому что этот символ будет интерпретирован как конец строки. Эта функция вернет ошибку -1, если в P(0) будет указан несуществующий сегмент. {{anchor:f62}} ==== Функция 62 ==== Прочитать строку из сегмента |<50% 10% 20% 70%>| ^Вход|P(0)|Сегмент| |:::|P(1)|Начальный адрес| |:::|P(2)|Увеличить P(1) если <>0| | ||| ^Выход|F$(1)|Строка| |:::| P(1)|P(1) + LEN(F$(1)) + 1, если P(2)<>0| Эта функция помещает в строковую переменную F$(1) строку, хранящуюся по указанному адресу заданного сегмента. Строка считается законченной когда встречается символ 0, или когда 80 знаков скопированы в F$(1). Если эта функция вызывается из обычного [[msx:basic:|]], строка не может содержать символа 255, потому что он, если будет найден, будет преобразован в символ 34 (кавычки); это происходит в соответствии с методом присвоения строк в Бейсике, в котором требуется специальная обработка кавычек. Это не происходит при вызове функции из [[msx:x-basic:|]]. Эта функция вернет ошибку -1, если в P(0) будет указан несуществующий сегмент. {{anchor:f63}} ==== Функция 63 ==== Инициализация режима мигания в SCREEN 0 |<50% 10% 20% 70%>| ^Вход|P(0)|Цвет "мигнувшего" текста| |:::|P(1)|Цвет "мигнувшего" фона| |:::|P(2)|Протяженность "включенного" состояния (0 to 15)| |:::|P(3)|Протяженность "выключенного" состояния (0 to 15)| | ||| ^Выход| — || Если P(2) и P(3) оба равны нулю 0, эта функция просто очищает зону мигания в VRAM. Эта функция инициализирует цвета и интервалы режима мигания в SCREEN 0, и очищает область VRAM, предназначенную для хранения координат мигающих знакомест. Если P(2) и P(3) нулевые, то будет выполнено только последнее. Эта функция может исполняться только в режиме SCREEN 0 с как минимум 41 столбцами; в противном случае, ничего не будет сделано, кроме возврата ошибки -1. Действия, которые реализуются этой функцией, могут быть также выполнены независимо, из Бейсика, следующим образом: ^Установка цветов|VDP(13) = Цвет текста + 16*Цвет фона| ^Установка интервалов|VDP(14) = Протяженность "включенного" состояния + 16*Протяженность "выключенного" состояния| ^Очищение области VRAM|Заполнение нулями 256-байтной области VRAM, которая начинается с адреса &H0A00| Системные переменные FORCLR (&HF3E9) и BAKCLR (&HF3EA) содержат соответственно текущий цвет текста и текущий цвет фона, ранее установленные оператором COLOR. Таким образом, чтобы достичь визуального эффекта инверсии, просто выполните: P(0)=PEEK(&HF3EA):P(1)=PEEK(&HF3E9):P(2)=15:P(3)=0:?USR(63) или VDP(13)=PEEK(&HF3EA)+16*PEEK(&HF3E9):VDP(14)=&HF0 {{anchor:f64}} ==== Функция 64 ==== Создать или удалить мигающий блок символов |<50% 10% 20% 70%>| ^Вход|P(0)|0 чтобы удалить блок \\ <> 0 чтобы создать блок| |:::|P(1)|Начальная X-координата (столбец) (от 0 до 79)| |:::|P(2)|Начальная Y-координата (строка) (от 0 до 27)| |:::|P(3)|Размер по X (столбцов)| |:::|P(4)|Размер по Y (строк)| |:::|P(5)|Увеличить P(1), если <>0| |:::|P(6)|Увеличить P(2), если <>0| | ||| ^Выход| P(1)|P(1) + P(3), если P(5)<>0| |:::|P(2)|P(2) + P(4), если P(6)<>0| Эта функция создает или удаляет блок мигающих знакомест определенных размеров с заданными координатами. Рекомендуется вызывать функцию 63, прежде чем использовать данную функцию. Эта функция может исполняться только в режиме SCREEN 0 с как минимум 41 столбцами; в противном случае — ничего не будет сделано, но не будет возвращено никакой ошибки. Если P(1)>79 и/или P(2)>27, будет выдана ошибка -1. Эта функция не проверяет, выходит ли блок за пределы экрана. Если блок заходит за столбец 79, он продолжается в столбце 0 следующей строки. Но если часть блока выходит за строку 27, эта часть не будет отображена. {{anchor:f65}} ==== Функция 65 ==== Получить информацию о прерываниях |<50% 10% 20% 70%>| ^Вход| — || | ||| ^Выход|P(0)|-1 если активен какой-либо процесс, работающий от прерываний (прерывание, определяемое пользователем, звуковой эффект PSG или воспроизведение музыки)| |:::|P(1)|-1 если активно прерывание, определяемое пользователем| |:::|P(2)|Сегмент прерывания, определяемого пользователем| |:::|P(3)|Адрес прерывания, определяемого пользователем| |:::|P(4)|-1 если проигрывается звуковой эффект PSG| |:::|P(5)|-1 если воспроизводится музыка| P(2) и P(3) вернут сегмент и адрес прерывания, определяемого пользователем, даже если оно приостановлено. Если пользовательского прерывания не было определено, оба параметра будут нулевыми. Чтобы получить больше информации о воспроизводимом звуковом эффекте, используйте [[#f67|функцию 67]]. Для музыки, используйте [[#72|функцию 72]]. {{anchor:f66}} ==== Функция 66 ==== Задать или приостановить прерывание, определяемое пользователем |<50% 10% 20% 70%>| ^Вход|P(0)|0 для приостановки действующего пользовательского прерывания \\ 1 задать и запустить пользовательское прерывание \\ -1 инвертировать текущее состояние пользовательского прерывания (запущено <- -> остановлено)| |:::|P(1)|Сегмент прерывания пользователя (игнорируется, если P(0)<>1)| |:::|P(2)|Адрес прерывания пользователя (игнорируется, если P(0)<>1)| | ||| ^Выход| — || Эта функция задает или останавливает программу, работающую от определяемого пользователем прерывания, то есть, программа в машинном коде, которая будет запускаться при каждом прерывании от таймера, 50 или 60 раз в секунду. NB: Указанный сегмент будет подключен в страницу 2 для исполнения программы, а следовательно, код должен быть собран под адреса в интервале &H8000–&HBFFF. Если P(0)=1, прерывание определяется через P(1) и P(2), и активируется (исполняется на 50 или 60 Гц). Если P(0)=0, прерывание приостанавливается (не исполняется более), но его определение не изменяется. Если P(0)=-1, его состояние инвертируется (с активного на приостановленное, и наоборот), и его определение не изменяется. Сегмент прерывания будет подключен в страницу 2 для исполнения программы, а значит код должен быть собран под адреса в интервале &H8000–&HBFFF. BIOS подключен в страницу 0, а сегмент NestorBASIC'а доступен в странице 1. Это состояние должно быть восстановлено самой программой перед возвратом, если осуществлялось переключение слотов/сегментов. Также, прерывания будут запрещены и должны оставаться таковыми в ходе исполнения программы. Сохранения регистров не требуется, потому что NestorBASIC обеспечит это. Некоторые из внутренних процедур и переменных NestorBASIC (для управления RAM и VRAM, а также для получения информации о процессах, работающих от прерываний, среди прочего) могут быть использованы программами прерываний, определяемых пользователем. В приложении 2 находится перечень и подробное описание этих процедур и переменных. Вы не можете определить код программы пользовательского прерывания в сегменте VRAM, а также в сегменте 255. Если Вы укажете несуществующий или неверный сегмент в P(1), функция выдаст ошибку -1. Если задать значение, отличное от 0, 1 или -1 в P(0), будет выдана ошибка 7. {{anchor:n108}} ===== 10.8. Звуковые эффекты PSG ===== {{anchor:f67}} ==== Функция 67 ==== Получить информацию о звуковых эффектах PSG |<50% 10% 20% 70%>| ^Вход|P(0)|Новая максимальная громкость (от 0 до 15, -1 чтобы оставить без изменений)| | ||| ^Выход|P(1)|-1 если проигрывается звуковой эффект| |:::|P(2)|Номер воспроизводимого звукового эффекта (далее SFX), или последнего воспроизведенного| |:::|P(3)|Приоритет воспроизводимого SFX, или последнего воспроизведенного| |:::|P(4)|Сегмент набора эффектов| |:::|P(5)|Адрес начала набора SFX| |:::|P(6)|Наивысший определенный номер эффекта| |:::|P(7)|Максимальная громкость| Результаты, возвращаемые данной функцией, будут действительны только если набор SFX был инициализирован [[#f68|функцией 68]]. Набор эффектов создается с помощью редактора SEE v3.xx, разработанного Fuzzy Logic. Эта функция не возвращает никаких ошибок. Если значение, указанное в P(0), больше, чем 15, оно будет истрактовано как 15. {{anchor:f68}} ==== Функция 68 ==== Инициализация набора звуковых эффектов PSG |<50% 10% 20% 70%>| ^Вход|P(0)|Сегмент| |:::|P(1)|Адрес| | ||| ^Выход| — || Эта функция инициализирует набор звуковых эффектов, хранящийся в указанных сегменте и адресе, оставляя его готовым к использованию [[#f69|функцией 69]]. Набор SFX создается с помощью редактора SEE v3.xx от Fuzzy Logic; если формат набора некорректен, функция выдаст ошибку 8. Не допускается использование набора SFX, находящегося в сегменте VRAM или 255–м сегменте. Если в P(0) был указан несуществующий сегмент, произойдет ошибка -1. {{anchor:f69}} ==== Функция 69 ==== Воспроизвести звуковой эффект PSG |<50% 10% 20% 70%>| ^Вход|P(0)|Номер эффекта| |:::|P(1)|Приоритет (0: низкий, <>0: высокий)| | ||| ^Выход| — || Эта функция запускает проигрывание указанного SFX эффекта; набор эффектов создается с помощью редактора SEE v3.xx, созданного Fuzzy Logic. Если набор SFX не был инициализирован [[#f68|функцей 68]], то поведение непредсказуемо. P(1) управляет приоритетом в случае попытки воспроизвести эффект, когда уже воспроизводится другой. Это работает следующим образом: * Если новый и уже воспроизводимый SFX имеют одинаковый приоритет, то воспроизводимый SFX останавливается, и проигрывается новый. * Если воспроизводимый SFX имеет низкий приоритет, а новый - высокий, то происходит то же самое. * Если воспроизводимый SFX имеет высокий приоритет, а новый SFX - низкий, то старый SFX продолжает звучать, и функция возвращает ошибку 11. Если звуковой эффект, указанный в P(0), не определен (первый трэк установлен в "OFF" в редакторе), функция вернет код ошибки 9. Если эффект не существует (его номер больше, чем последний определенный номер эффекта), функция вернет код ошибки 10. {{anchor:f70}} ==== Функция 70 ==== Остановить воспроизведение звукового эффекта PSG |<50% 10% 20% 70%>| ^Вход| — || | ||| ^Выход| — || Эта функция останавливает воспроизведение звукового эффекта PSG, если таковой проигрывался, и заглушает PSG. Функция не выдает ошибок. {{anchor:n109}} ===== 10.9. Функции для воспроизведения музыки в формате MoonBlaster ===== {{anchor:f71}} ==== Функция 71 ==== Загрузка и инициализация, или выгрузка Moonblaster-плеера (S4) |<50% 10% 20% 70%>| ^Вход|P(0)|Какой плеер загрузить: \\ 0: Moonblaster 1.4 \\ 1: Moonblaster Wave 1.05 \\ 3: Автоопределение: Загрузить плеер Moonblaster Wave если присутствует Moonsound, иначе загрузить Moonblaster 1.4. \\ -1: Выгрузить загруженный в текущий момент проигрыватель| | ||| ^Выход|P(0)|Загруженный плеер (0, 1 или -1, как выше).| |:::|P(1)|-1 -> Нет ошибки \\ <> -1 -> Произошла ошибка диска, и NBASIC.BIN остался открытым под этим номером; код ошибки возвращается командой USR, как обычно.| Эта функция загружает указанный MoonBlaster–плеер в сегмент 5, оставляя готовым к использованию. Также, производит поиск всех присутствующих в системе звуковых чипов, и оставляет все найденные чипы включенными (см. [[#f73|функцию 73]], чтобы узнать больше подробностей об активации звуковых чипов). Проигрыватель может быть загружен только если сегмент 5 существует и принадлежит первичному мапперу; в противном случае, функция выдаст ошибку -1. Если случается дисковая ошибка, функция возвращает соответствующий код ошибки (см. [[#n4|раздел 4]]). Если NBASIC.BIN в результате ошибки остается открытым, его соответствующий номер файла будет в P(1); иначе, P(1) будет -1. Файл NBASIC.BIN содержит две версии плеера Moonblaster Wave: одна из них — для MSX2/2+ и Turbo-R в режиме Z80, а другая - для Turbo-R в режиме R800. Если компьютер является Turbo-R, то NestorBASIC решает, какую версию загрузить в зависимости от работающего процессора в момент вызова функции 71. Заметьте, что если произведено переключение процессора, эта функция должна быть вызвана снова чтобы загрузить подходящий плеер: версия для Z80 не работает в режиме R800, а версия для R800 привносит замедление в режиме Z80. Чтобы выгрузить плеер, используйте эту функцию с P(0)=-1 на входе; Вам не нужно предварительно останавливать воспроизводимую музыку, так как функция позаботится об этом сама. После выгрузки проигрывателя (которая заключается просто в удалении строки "NestorPlayer" в начале сегмента 5), сегмент 5 снова становится доступным, как любой другой. Если Вы попытаетесь выгрузить проигрыватель когда никакой плеер не загружен, функция не сделает ничего и не выдаст никакой ошибки. Можно загружать, выгружать и загружать снова MoonBlaster–плееры столько раз, сколько понадобится, в ходе выполнения программы. Если какой-то проигрыватель загружен, его легко можно заменить на другой, что очень удобно. {{anchor:f72}} ==== Функция 72 ==== Получить информацию о проигрываемой музыке |<50% 10% 20% 70%>| ^Вход| — || | ||| ^Выход|P(0)|-1 если проигрывается музыка (или стоит на паузе)| |:::|P(1)|1 если проигрывается музыка Moonblaster 1.4 (или стоит на паузе)| |:::|P(2)|1 если проигрывается музыка Moonblaster Wave (или стоит на паузе)| |:::|P(3)|0| |:::|P(4)|-1 если музыка стоит на паузе| |:::|P(5)|Сегмент проигрываемой музыки, или сегмент последней воспроизводившейся музыки| |:::|P(6)|Начальный адрес проигрываемой музыки, или начальный адрес последней воспроизводившейся музыки| |:::|P(7)|Текущая позиция| |:::|P(8)|Текущий шаг (от 0 до 15)| |:::|P(9)|-1 если MSX-MUSIC был найден| |:::|P(10)|-1 если MSX-AUDIO был найден| |:::|P(11)|-1 если OPL4 был найден| |:::|P(12)|-1 если проигрыватель загружен и инициализирован| |:::|P(13)|Загруженный в данный момент плеер (только если P(12)=-1): \\ 0: Moonblaster 1.4 \\ 1: Moonblaster Wave 1.05| |:::|F$(0)|Имя мелодии (пустая строка, если никакая не проигрывается)| |:::|F$(1)|Имя Samplekit'а или wavekit'а (пустая строка, если никакая музыка не проигрывается)| Если не загружен никакой плеер, в P(12) будет ноль, остальные выходные параметры не будут выставлены (кроме P(9)–P(11)); функция не возвращает никаких ошибок. Для загрузки плеера используйте [[#f71|функцию 71]]. Если никакая музыка не воспроизводится, в P(5) и P(6) будут возвращены позиция и шаг, где последняя проигрываемая мелодия была остановлена, а F$(0) и F$(1) будут пустыми строками. В противном случае, в F$(0) будет содержаться имя мелодии (всегда 40 символов для музыки Moonblaster 1.4, 50 для музыки Moonblaster Wave) F$(1) будет содержать имя samplekit'а или wavekit'а, который был загружен в Moonblaster на момент сохранения композиции, заглавными буквами и без расширения ("NONE", если никакого samplekit'а не было загружено). В P(9)–P(11) возвращается информация о обнаруженных звуковых устройствах, даже когда проигрыватель не загружен. Чтобы узнать информацию об активных звуковых устройствах, используйте [[#f73|функцию 73]]. {{anchor:f73}} ==== Функция 73 ==== Активация и деактивация звуковых устройств |<50% 10% 20% 70%>| ^Вход|P(0)|0 -> Только запросить информацию \\ 1 -> Включить или выключить устройства согласно P(1)–P(3) \\ 2 -> Включить все найденные звуковые устройства| |:::|P(1)|0 -> Не менять состояние [[msx:music:|]] \\ 1 -> Отключить [[msx:music:|]] \\ 2 -> Включить [[msx:music:|]] \\ -1 -> Инвертировать состояние [[msx:music:|]]| |:::|P(2)|0 -> Не менять состояние [[msx:audio|]] \\ 1 -> Отключить [[msx:audio|]] \\ 2 -> Включить [[msx:audio|]] \\ -1 -> Инвертировать состояние [[msx:audio|]]| |:::|P(3)|0 -> Не менять состояние OPL4 \\ 1 -> Отключить OPL4 \\ 2 -> Включить OPL4 \\ -1 -> Инвертировать состояние OPL4| | ||| ^Выход|P(4)|0 -> [[msx:music:|]] отсутствует \\ 1 -> [[msx:music:|]] присутствует, но отключен \\ 2 -> [[msx:music:|]] включен| |:::|P(5)|0 -> [[msx:audio|]] отсутствует \\ 1 -> [[msx:audio|]] присутствует, но отключен \\ 2 -> [[msx:audio|]] включен| |:::|P(6)|0 -> OPL4 отсутствует \\ 1 -> OPL4 присутствует, но отключен \\ 2 -> OPL4 включен| Эта функция позволяет отключать [[msx:music:|]], [[msx:audio|]] и OPL4, которые, в этом состоянии, не будут использоваться, несмотря на то, что были обнаружены в системе. Эта возможность будет полезна, например, для прослушивания только [[msx:audio|]]–части композиции на компьютере со встроенным [[msx:music:|]]. Если P(0)=0, функция только выдаст сведения об активных звуковых устройствах в P(4)–P(5), и не изменит их состояние. Если P(0)=2, все найденные звуковые устройства будут включены (это действие по-умолчанию при загрузке плеера). Для получения сведений о присутствии звуковых устройств используйте [[#f72|функцию 72]]. Если P(0)=1, звуковые устройства будут активированы либо отключены согласно значениям, переданным в P(1)–P(3); попытки активировать устройства, которые отсутствуют в системе, будут проигнорированы. Если отключен и [[msx:audio|]], и [[msx:music:|]] (Moonblaster 1.4 player), или отключен OPL4 (Moonblaster Wave player), [[#f74|функция 74]] (начало воспроизведения музыки) не будет ничего делать, но не выдаст никакой ошибки. Изменения, сделанные этой функцией, не вступят в силу, пока играющая музыка не будет остановлена ([[#75|функция 75]] или [[#f77|77]]), и запущена по новой ([[#f74|функция 74]]). Если никакой музыки не воспроизводилось в момент, когда Вы использовали данную функцию, просто стартуйте воспроизведение, обычным образом. Эта функция вернет код ошибки 7, если какой-либо из входящих параметров не корректен (но если P(0)<>1, не требуется устанавливать P(1)–P(3)), и код ошибки 12, если плеер не загружен. {{anchor:f74}} ==== Функция 74 ==== Старт воспроизведения Moonblaster–музыки |<50% 10% 20% 70%>| ^Вход|P(0)|Сегмент, в котором хранится музыка| |:::|P(1)|Начальный адрес музыки| | ||| ^Выход| — || Эта функция запускает воспроизведение указанной Moonblaster–музыки. Если заданный сегмент не существует, является сегментом VRAM или 255–м, произойдет ошибка -1. Если не был загружен плеер, соответствующий типу музыки, возникнет ошибка 12 (используйте для загрузки проигрывателя [[#f71|функцию 71]]). Композиции Moonblaster Wave могут находиться в нескольких смежных сегментах; подробности см. в [[#n82|разделе 8.2]]. В случае с плеером Moonblaster 1.4, данная функция проверяет первый байт данных по указанному адресу; если там &HFF, то это означает, что композиция была сохранена в режиме EDIT, и, следовательно, не может быть воспроизведена; в таком случае будет выдана ошибка 13. Иначе, NestorBASIC считает, что по заданному адресу расположена Moonblaster–музыка, сохраненная в режиме USER, и начинает воспроизведение без дальнейших проверок. Если означенная область памяти не содержит Moonblaster–музыки, результат будет непредсказуемым. Проигрыватель Moonblaster Wave не имеет подобных недостатков: он может определять, действительно ли по заданному адресу содержится музыка Moonblaster Wave, и что она записана в режиме USER. Если нет, то выдается ошибка 13. Если и [[msx:music:|]], и [[msx:audio|]] были деактивированы (музыка Moonblaster 1.4), или OPL4 был деактивирован (музыка Moonblaster Wave) [[#f73|функцией 73]], данная функция не произведёт никаких действий, и не выдаст никакой ошибки. Если в данный момент уже воспроизводится, или стоит на паузе, другая музыка — случится ошибка 14. {{anchor:f75}} ==== Функция 75 ==== Останов воспроизведения музыки |<50% 10% 20% 70%>| ^Вход| — || ^Выход| — || Эта функция останавливает воспроизведение музыки и заглушает звуковые устройства. Если никакая музыка не играет в этот момент, или ни один музыкальный проигрыватель не загружен, функция не выполнит никаких действий. Она не возвращает ошибок. {{anchor:f76}} ==== Функция 76 ==== Постановка на паузу и продолжение воспроизведения музыки |<50% 10% 20% 70%>| ^Вход|P(0)|0 -> Поставить музыку на паузу \\ 1 -> Продолжить воспроизведение \\ -1 -> Инвертировать текущее состояние (играть <--> пауза)| | ||| ^Выход| — || Эта функция приостанавливает или возобновляет воспроизведение Moonblaster–музыки. Если никакая музыка не воспроизводится и не стоит на паузе, или проигрыватель не загружен, функция не будет ничего делать и не выдаст никакой ошибки. Если входной параметр недействителен, будет возвращена ошибка с кодом 7. {{anchor:f77}} ==== Функция 77 ==== Постепенное затухание музыки |<50% 10% 20% 70%>| ^Вход|P(0)|0 -> Только запросить информацию \\ -1 -> Приостановить затухание \\ 1..254 -> Начать/продолжить затухание с заданным интервалом| | ||| ^Выход|P(1)|1 если музыка в процессе затухания| |:::|P(2)|Интервал задержки происходящего затухания \\ (-1 если затухание приостановлено)| Эта функция стартует затухание проигрываемой музыки. Интервал задержки это число тактов (1/50 или 1/60 секунды каждый) между шагами затухания, так, что наименьшая задержка соответствует наиболее быстрому затуханию. Как только затухание завершилось (громкость музыки уменьшилась до нуля), воспроизведение будет автоматически остановлено: Вам не придется останавливать его директивно [[#f75|функцией 75]]. Если P(0)=-1, угасание будет приостановлено, то есть, музыка продолжит играть обычным образом, с достигнутым уровнем громкости. Чтобы возобновить затухание, просто вызовите эту функцию снова, указав новое значение задержки в P(0). Если P(0)=0, данная функция только вернет в P(1) и P(2) актуальные значения. Если никакая музыка не играет, или проигрыватель не загружен, функция не сделает ничего. Она не возвращает ошибок. {{anchor:f78}} ==== Функция 78 ==== Загрузка samplekit-а для Phillips NMS 1205 Music Module (S4) |<50% 10% 20% 70%>| ^Вход|P(0)|Номер файла| | ||| ^Выход|P(7)|Количество загруженных байт| Эта функция загружает из указанного открытого файла samplekit (набор сэмплов) для Phillips Music Module, который должен быть записан в формате Moonblaster: 56 байт заголовка, которые будут скопированы в соответствующую область плеера; и 32Кб сэмплов, которые будут переданы в sample-RAM Music Modul-я. Данные будут считаны из предварительно открытого файла. Это позволяет Вам совмещать samplekit с другими данными в одном и том же файле: в таком случае, достаточно поместить файловый указатель в нужное место, и затем вызвать данную функцию. Однако, как правило, чаще всего требуется загрузить MBK–файл, созданный непосредственно в Moonblaster–е. В таком случае, Вы можете загрузить samplekit, просто выполнив следующее: F$(0)="sampkit.mbk":?USR(31):?USR(78):?USR(32) Если случилась дисковая ошибка, функция вернет соответствующий код ошибки, и число прочитанных байт будет содержаться в P(7). Если это число больше 16Кб, то только первые 16Кб samplekit-a было передано в sample-RAM. Если меньше, то значит никаких данных не было передано в sample-RAM. Если плеер был не загружен, или Music Module не найден, данная функция не совершит никаких действий и не выдаст ошибки. Если весь samplekit успешно загружен, в P(7) вернется не 32824, а -32712, соответственно диапазону целочисленных переменных (-32768 to 32767) [[msx:basic:|]]. {{anchor:f79}} ==== Функция 79 ==== Загрузить wavekit для Moonsound(S4) |<50% 10% 20% 70%>| ^Вход|P(0)|Номер файла| | ||| ^Выход|P(6):P(7)|Количество прочитанных байт| Эта функция загружает из указанного открытого файла wavekit для Moonsound, который должен быть записан в формате USER (иначе, случится ошибка 15). Данные будут считаны из предварительно открытого файла. Это позволяет хранить samplekit в одном файле с другими данными: в таком случае, достаточно поместить файловый указатель в нужное место, и затем вызвать данную функцию. Однако, как правило, чаще всего требуется загрузить MWK-файл, созданный непосредственно в редакторе Moonblaster Wave. В этом случае, Вы можете загрузить samplekit, просто выполнив следующее: F$(0)="wavkit.mwk":?USR(31):?USR(79):?USR(32) Если случилась дисковая ошибка, функция вернет соответствующий код ошибки, и число прочитанных байт будет содержаться в P(6):P(7). В таком случае, память сэмплов Moonsound могла быть изменена, но рабочая область проигрывателя не была обновлена, поэтому нельзя считать, что wavekit был частично загружен. Если плеер Moonblaster Wave не был загружен, или не было найдено Moonsound-а в системе, функция не осуществит никаких действий и не выдаст ошибки. Если весь wavekit был успешно загружен, P(6):P(7) будут содержать размер wavekit-а (будет равен размеру файла, если Вы просто загрузили .MWK файл). {{anchor:n1010}} ===== 10.10. Функции назначения количества сегментов ОЗУ для использования NestorBasic ===== {{anchor:f80}} ==== Функция 80 ==== Узнать или задать количество сегментов выделенных для NestorBASIC |<50% 10% 20% 70%>| ^Вход|P(0)|Число сегментов, выделяемых NestorBASIC \\ (0: Не изменять, только получить число выделенных на данный момент сегментов) \\ Это число включает также сегменты NestorBASIC, [[msx:x-basic:|]], и основного ОЗУ [[msx:basic:|]]| | ||| ^Выход|P(0)|Число сегментов, выделенных NestorBASIC в результате исполнения функции| |:::|P(1)|Максимальное число сегментов, которые могут быть выделены для NestorBASIC| Эта функция работает и в [[msx:dos:|]], и в [[msx:dos2:|]], как бы то ни было, она предназначена для применения в [[msx:dos2:|]]. Под [[msx:dos2:|]], NestorBASIC, инициализируясь после загрузки, резервирует для себя все свободные сегменты в системе, вплоть до 247-го. Это означает, что не останется свободных сегментов для других резидентных программ, которые тоже осуществляют аллокацию памяти — такие как [[msx:dos2:|]] RAM-диск, [[msx:nestorman:|]] или [[msx:internestor_suite:|]]. Решение этой проблемы заключается в использовании этой функции для того, чтобы сообщить NestorBASIC, сколько сегментов реально нужно; остальные сегменты будут будут освобождены и станут доступными для других программ. Например, если Вы собираетесь использовать музыкальный плеер (который загружается в сегмент 5), и Вам нужен лишь один дополнительный сегмент для данных, тогда нужно вызвать эту функцию с P(0)=7; дополнительный сегмент будет номер 6. Если в P(0) задано количество сегментов меньше 6, NestorBASIC выделит 5 сегментов (см. раздел 2), или 6 если проигрыватель музыки был загружен. Если задано число сегментов, большее, чем общее количество доступных сегментов, то будет зарезервировано столько сегментов, сколько возможно (вплоть до 247), и в P(0) вернется число сегментов, которое было в действительности выделено. В любом случае, данная функция не выдаст никакой ошибки. Под [[msx:dos:|]], всё, что делает эта функция - только изменяет некоторые внутренние переменные NestorBASIC; значение, возвращаемое в P(1), фиксированное и вычисляется во время первоначального запуска NestorBASIC. Под [[msx:dos2:|]], напротив, происходит реальное выделение и освобождение сегментов с использованием процедур [[msx:dos2:|]] для работы с маппером; в этом случае, значение, возвращаемое в P(1), пересчитывается при каждом вызове функции, и зависит от того, сколько сегментов было зарезервировано другими резидентными программами. {{anchor:n1011}} ===== Функции для взаимодействия с NestorMan и InterNestor Suite/Lite ===== {{anchor:f81}} ==== Функция 81 ==== Проверка присутствия [[msx:nestorman:|]] и [[msx:internestor_suite:|]] в ОЗУ |<50% 10% 20% 70%>| ^Вход| — || | ||| ^Выход|P(0)|0 если [[msx:nestorman:|]] не присутствует \\ 1 если [[msx:nestorman:|]] присутствует \\ 3 если и [[msx:nestorman:|]], и [[msx:internestor_suite:|]] присутствуют| |:::|P(1)|[[msx:nestorman:|]]-сегмент модуля [[msx:internestor_suite:|]] level 1| |:::|P(2)|[[msx:nestorman:|]]-сегмент модуля [[msx:internestor_suite:|]] level 2| |:::|P(3)|[[msx:nestorman:|]]-сегмент модуля [[msx:internestor_suite:|]] level 3| |:::|P(4)|[[msx:nestorman:|]]-сегмент модуля [[msx:internestor_suite:|]] level 4| |:::|P(5)|Номер сегмента [[msx:nestorman:|]] сегмента 4 NestorBASIC| Значение, возвращаемое в P(5) будет действительно, только если P(0) равно 1 или 3 на выходе. Это значение требуется для того, чтобы осуществлять обмен данными между сегментом [[msx:nestorman:|]] и сегментом NestorBASIC, используя сегмент 4 (общий для обей программ) как промежуточный буфер, как описано в [[#n92|разделе 9.2]]. Значения, возвращаемые в P(1)–P(4), будут действительны только если P(0) равно 3 на выходе. Не обязательно знать расположение модулей [[msx:internestor_suite:|]], чтобы вызывать его подпрограммы (используя [[#f85|функцию 85]]), но это необходимо знать, чтобы читать и записывать конфигурационные константы и переменные модулей, как описано в [[#n93|разделе 9.3]]. {{anchor:f82}} ==== Функция 82 ==== Выполнить функцию [[msx:nestorman:|]] ^Вход|P(0)|Номер функций P(2)–P(11) = Регистры на входе функции: \\ P(2) = AF P(8) = AF' \\ P(3) = BC P(9) = BC' \\ P(4) = DE P(10)= DE' \\ P(5) = HL P(11)= HL' \\ P(6) = IX \\ P(7) = IY| ^Выход|P(2)–P(12)| = Регистры на выходе функции, с тем же назначением, что и на входе, плюс следующие: \\ P(12) = A \\ P(13) = Флаг Cy (-1 если установлен, иначе 0) \\ P(14) = Флаг Z (-1 если установлен, иначе 0)| Эта функция вызывает функцию [[msx:nestorman:|]], указанную в P(0), посредством метода непрямого вызова, то есть, используя hook расширенного BIOS. Таким образом, это равносильно использованию функции 58 с установленными предварительно P(1)=&HFFCA, P(3)=Функция+256*B, и P(4)=&H2202. Функцией будет возвращен код ошибки -1, если [[msx:nestorman:|]] отсутствует. Отметьте, тем не менее, что не производится проверка, существует ли действительно в [[msx:nestorman:|]] указанная функция. См. также описание [[#f58|функции 58]] для понимания выходных значений P(12)–P(14). [[#n9|Раздел 9]] демонстрирует некоторые техники для обмена данными между [[msx:nestorman:|]] и NestorBASIC. {{anchor:f83}} ==== Функция 83 ==== Передача блока данных из сегмента [[msx:nestorman:|]] в сегмент NestorBASIC |<50% 10% 20% 70%>| ^Вход|P(0)|[[msx:nestorman:|]]–сегмент источника| |:::|P(1)|Начальный адрес источника| |:::|P(2)|NestorBASIC–сегмент назначения| |:::|P(3)|Начальный адрес назначения| |:::|P(4)|Длина блока данных| |:::|P(5)<> 0|Автоинкремент P(1)| |:::|P(6)<>0|Автоинкремент P(3)| | ||| ^Выход|P(1)|P(1) + P(4) если P(5)<>0| |:::|P(3)|P(3) + P(4) если P(6)<>0| Эта функция идентична функции 10, кроме того, что значение, передаваемое через P(0) соотносится с сегментом [[msx:nestorman:|]]. Как и в случае с функцией 10, P(3)+P(4) должно быть меньше &H4000, в P(2) может быть указан сегмент VRAM или 255–й сегмент, и ошибка -1 будет выдана, если любой из указанных сегментов не существует. У данной функции есть одно ограничение: её нельзя использовать, указав сегмент 1 в качестве NestorBASIC–сегмента назначения. Как правило, это не является проблемой, потому что 1–й сегмент содержит компилятор [[msx:x-basic:|]], и обычно никому не нужно менять его содержимое. Если, тем не менее, передача в 1-й сегмент необходима, Вам придется сначала скопировать данные в какой-то другой сегмент, в качестве промежуточного шага — например, в сегмент 4. {{anchor:f84}} ==== Функция 84 ==== Передача блока данных из сегмента NestorBASIC в сегмент NestorMan ^Вход|P(0)|NestorBASIC-сегмент источника| |:::|P(1)|Начальный адрес источника| |:::|P(2)|[[msx:nestorman:|]]–сегмент назначения| |:::|P(3)|Начальный адрес назначения| |:::|P(4)|Длина блока данных| |:::|P(5)<> 0|Автоинкремент P(1)| |:::|P(6)<> 0|Автоинкремент P(3)| ^Выход|P(1)|P(1) + P(4) если P(5)<>0| |:::|P(3)|P(3) + P(4) если P(6)<>0| Эта функция идентична функции 10, кроме того, что значение, передаваемое через P(2) соотносится с сегментом [[msx:nestorman:|]]. Как и в случае с функцией 10, P(3)+P(4) должно быть меньше &H4000, в P(0) может быть указан сегмент VRAM или 255–й сегмент, и ошибка -1 будет выдана, если любой из указанных сегментов не существует. У данной функции есть одно ограничение: её нельзя использовать, указав сегмент 1 в качестве NestorBASIC–сегмента источника. Как правило, это не является проблемой, потому что 1–й сегмент содержит компилятор [[msx:x-basic:|]], и обычно никому не нужно менять его содержимое. Если, тем не менее, передача в 1–й сегмент необходима, Вам придется сначала скопировать данные в какой-то другой сегмент, в качестве промежуточного шага - например, в сегмент 4. {{anchor:f85}} ==== Функция 85 ==== Вызов процедуры [[msx:internestor_suite:|]] |<50% 10% 20% 70%>| ^Вход|P(0)|Номер модуля, от 1 до 4| |:::|P(1)|Адрес подпрограммы| |:::|P(2)–P(11)|Регистры на входе процедуры: \\ P(2) = AF P(8) = AF' \\ P(3) = BC P(9) = BC' \\ P(4) = DE P(10)= DE' \\ P(5) = HL P(11)= HL' \\ P(6) = IX \\ P(7) = IY| | ||| ^Выход|P(2)–P(12)|Регистры на выходе процедуры, с тем же назначением, что и на входе, плюс следующие: \\ P(12) = A \\ P(13) = Флаг Cy (-1 если установлен, иначе 0) \\ P(14) = Флаг Z (-1 если установлен, иначе 0)| С помощью этой функции можно вызвать любую подпрограмму любого из модулей [[msx:internestor_suite:|]]. Чтобы читать или изменять конфигурационные константы и переменные модулей, нужно сначала узнать номера [[msx:nestorman:|]]-сегментов модулей, используя [[#f81|функцию 81]], а затем применить любой из приемов, описанных в [[#n92|разделе 9.2]], для обмена данными между NestorBASIC и [[msx:nestorman:|]]. Данная функция выдаст ошибку -1, если [[msx:internestor_suite:|]] отсутствует в памяти, или в P(0) указан недействительный номер модуля. См. также описание [[#f58|функции 58]] для понимания выходных значений P(12)–P(14). [[#n93|Раздел 9.3]] содержит некоторые соображения насчет совместного использования NestorBASIC и [[msx:internestor_suite:|]]. {{anchor:f86}} ==== Функция 86 ==== Вызов процедуры InterNestor Lite |<50% 10% 20% 70%>| ^Вход|P(1)|Адрес процедуры| |:::|P(2) - P(11)|Регистры на входе процедуры: \\ P(2) = AF P(8) = AF' \\ P(3) = BC P(9) = BC' \\ P(4) = DE P(10)= DE' \\ P(5) = HL P(11)= HL' \\ P(6) = IX \\ P(7) = IY| | ||| ^Выход|P(2)–P(12)|Регистры на выходе процедуры, с тем же назначением, что и на входе, плюс следующие: \\ P(12) = A \\ P(13) = Флаг Cy (-1 если установлен, иначе 0) \\ P(14) = Флаг Z (-1 если установлен, иначе 0)| С помощью этой функции можно вызвать любую процедуру [[msx:internestor_lite:|]]. P(1) должен содержать адрес какой-либо из подпрограмм [[msx:internestor_lite:|]], перечисленных в его руководстве программиста, иначе результаты исполнения данной функции непредсказуемы. Данная функция выдаст ошибку -1, если [[msx:internestor_lite:|]] отсутствует в памяти. Чтобы заранее узнать, загружен [[msx:internestor_lite:|]] или нет, используйте следующий код, в котором применяется метод обнаружения, описанный в [[#n94|разделе 9.4]]: P(0)=0: P(1)=&HFFCA: P(2)=0: P(4)=&H2203: E=USR(58): IF P(12)=0 THEN ... (отсутствует) В [[#n94|разделе 9.4]] есть комментарий относительно применения процедур [[msx:internestor_lite:|]] для обмена данными с [[msx:dos:#tpa|TPA]] из NestorBASIC. См. также описание [[#f58|функции 58]] для понимания выходных значений P(12)–P(14). Следующий пример выводит номер версии [[msx:internestor_lite:|]], загруженного в данный момент. 10 BLOAD"nbasic.bin",R 20 IF P(0)<5 AND P(0)<>3 THEN PRINT "Error "+P(0):END 30 '* Check the presence of INL 40 P(0)=0: P(1)=&HFFCA: P(2)=0: P(4)=&H2203: E=USR(58): IF P(12)=0 THEN PRINT "InterNestor Lite is not present.":GOTO 100 50 '* The VERS_PAUSE routine(&H402A) returns the INL version in C.D.E and the implementation number in B, it must be called with A=0 60 P(1)=&H402A:P(2)=0:E=USR(86) 70 X=P(3):GOSUB 1000:RB=X '* B register 80 X=P(4):GOSUB 1000:RD=X '* D register 90 PRINT "InterNestor Lite version " ; P(3) AND &HFF ; "." ; RD ; "." ; P(4) AND &HFF ; ", implementation " ; RB ; " is present." 100 '* Unloads NestorBASIC and finishes 110 P(0)=1:E=USR(0):END 1000 '* This subroutine extracts the high byte of X 1010 X=((X AND &HFF00)/256) AND &HFF 1020 RETURN Программа TCPCON-L.BAS, поставляемая с NestorBASIC, является более сложным примером, который иллюстрирует совместную работу NestorBASIC и [[msx:internestor_lite:|]]. {{anchor:appendix}} {{anchor:a1}} ====== Приложение 1 ====== Функции, которые используют 4-й сегмент, имеют метку "(S4)" после их названий. \\ Это функции: 0, 26-28, 30, 33-41, 55-57, 71, 78, и 79. ^[[#n102|Общие функции]]^^ |[[#f0|Функция 0]]|Выгрузка NestorBASIC'а из памяти (S4)| |[[#f2|Функция 1]]|Получение общей информации о NestorBASIC и конкретном логическом сегменте| ^[[#n103|Функции для доступа к логическим сегментам]]^^ |[[#f2|Функция 2]]|Прочесть байт из сегмента| |[[#f3|Функция 3]]|Прочесть байт из сегмента с автоинкрементом адреса| |[[#f4|Функция 4]]|Прочесть целое число (2 байта) из сегмента| |[[#f5|Функция 5]]|Прочесть целое число (2 байта) из сегмента с автоинкрементом адреса| |[[#f6|Функция 6]]|Записать байт в сегмент| |[[#f7|Функция 7]]|Записать байт в сегмент с автоинкрементом адреса| |[[#f8|Функция 8]]|Записать целое число (2 байта) в сегмент| |[[#f9|Функция 9]]|Записать целое число (2 байта) в сегмент с автоинкрементом адреса| |[[#f10|Функция 10]]|Блочная пересылка данных между сегментами| |[[#f11|Функция 11]]|Заполнить область ОЗУ байтом| |[[#f12|Функция 12]]|Заполнить область ОЗУ байтом с автоинкрементом адреса| ^[[#n104|Функции доступа к VRAM]]^^ |[[#f13|Функция 13]]|Прочесть байт из VRAM| |[[#f14|Функция 14]]|Прочесть байт из VRAM с автоинкрементом адреса| |[[#f15|Функция 15]]|Прочесть целое число (2 байта) из VRAM| |[[#f16|Функция 16]]|Прочесть целое число (2 байта) из VRAM с автоинкрементом адреса| |[[#f17|Функция 17]]|Записать байт в VRAM| |[[#f18|Функция 18]]|Записать байт в VRAM с автоинкрементом адреса| |[[#f19|Функция 19]]|Записать целое число (2 байта) в VRAM| |[[#f20|Функция 20]]|Записать целое число (2 байта) в VRAM с автоинкрементом адреса| |[[#f21|Функция 21]]|Блочная пересылка данных из VRAM в RAM| |[[#f22|Функция 22]]|Пакетная пересылка данных из RAM в VRAM| |[[#f23|Функция 23]]|Пакетная пересылка данных в пределах VRAM| |[[#f24|Функция 24]]|Заполнить область VRAM байтом| |[[#f25|Функция 25]]|Заполнить область VRAM байтом с автоинкрементом адреса| ^[[#n105|Функции для работы с диском]]^^ |[[#f26|Функция 26]]|Поиск файла (S4)| |[[#f27|Функция 27]]|Переименование файла (S4)| |[[#f28|Функция 28]]|Удаление файла| |[[#f29|Функция 29]]|Перемещение файла (MSX-DOS 2)| |[[#f30|Функция 30]]|Создание файла или директории| |[[#f31|Функция 31]]|Открытие файла| |[[#f32|Функция 32]]|Закрытие файла| |[[#f33|Функция 33]]|Чтение из файла (S4)| |[[#f34|Функция 34]]|Чтение из файла в VRAM (S4)| |[[#f35|Функция 35]]|Чтение секторов диска (S4)| |[[#f36|Функция 36]]|Чтение секторов диска в VRAM (S4)| |[[#f37|Функция 37]]|Запись в файл (S4)| |[[#f38|Функция 38]]|Запись в файл из VRAM (S4)| |[[#f39|Функция 39]]|Запись в сектора диска (S4)| |[[#f40|Функция 40]]|Запись в сектора диска из VRAM (S4)| |[[#f41|Функция 41]]|Заполнение файла байтом (S4)| |[[#f42|Функция 42]]|Перемещение файлового указателя| |[[#f43|Функция 43]]|Узнать текущий диск и вектор доступных дисков (login vector)| |[[#f44|Функция 44]]|Задать текущий диск| |[[#f45|Функция 45]]|Информация о дисковом пространстве| |[[#f46|Функция 46]]|Узнать текущую директорию (MSX-DOS 2)| |[[#f47|Функция 47]]|Задать текущую директорию (MSX-DOS 2)| |[[#f48|Функция 48]]|Узнать размер RAM-диска (MSX-DOS 2)| |[[#f49|Функция 49]]|Создать RAM–диск (MSX-DOS 2)| |[[#f50|Функция 50]]|Получить атрибуты файла (MSX-DOS 2)| |[[#f51|Функция 51]]|Установить атрибуты файла (MSX-DOS 2)| |[[#f52|Функция 52]]|Синтаксический разбор пути (MSX-DOS 2)| ^[[#n106|Функции сжатия и распаковки графики]]^^ |[[#f53|Функция 53]]|Сжатие графических данных| |[[#f54|Функция 54]]|Распаковка графических данных| ^[[#n96|Функции для запуска программ на BASIC]]^^ |[[#f55|Функция 55]]|Запуск программы на BASIC, находящейся в сегменте (S4)| |[[#f56|Функция 56]]|Актуализация программы на BASIC, находящейся в сегменте (S4)| |[[#f57|Функция 57]]|Сохранить программу на BASIC со специальным заголовком (S4)| ^[[#n107|Другие различные функции]]^^ |[[#f58|Функция 58]]|Выполнение подпрограммы в машинном коде| |[[#f59|Функция 59]]|Выполнение подпрограммы пользователя| |[[#f60|Функция 60]]|Вывести строку на дисплей в графическом режиме| |[[#f61|Функция 61]]|Сохранить строку в сегмент| |[[#f62|Функция 62]]|Прочитать строку из сегмента| |[[#f63|Функция 63]]|Инициализация режима мигания в SCREEN 0| |[[#f64|Функция 64]]|Создать или удалить мигающий блок символов| |[[#f65|Функция 65]]|Получить информацию о прерываниях| |[[#f66|Функция 66]]|Задать или приостановить прерывание, определяемое пользователем| ^[[#n108|Звуковые эффекты PSG]]^^ |[[#f67|Функция 67]]|Получить информацию о звуковых эффектах PSG| |[[#f68|Функция 68]]|Инициализация набора звуковых эффектов PSG| |[[#f69|Функция 69]]|Воспроизвести звуковой эффект PSG| |[[#f70|Функция 70]]|Остановить воспроизведение звукового эффекта PSG| ^[[#n109|Функции для воспроизведения музыки в формате MoonBlaster]]^^ |[[#f71|Функция 71]]|Загрузка и инициализация, или выгрузка Moonblaster-плеера (S4)| |[[#f72|Функция 72]]|Получить информацию о проигрываемой музыке| |[[#f73|Функция 73]]|Активация и деактивация звуковых устройств| |[[#f74|Функция 74]]|Старт воспроизведения Moonblaster–музыки| |[[#f75|Функция 75]]|Останов воспроизведения музыки| |[[#f76|Функция 76]]|Постановка на паузу и продолжение воспроизведения музыки| |[[#f77|Функция 77]]|Постепенное затухание музыки| |[[#f78|Функция 78]]|Загрузка samplekit-а для Phillips NMS 1205 Music Module (S4)| |[[#f79|Функция 79]]|Загрузить wavekit для Moonsound(S4)| ^[[#n1010|Функции назначения количества сегментов ОЗУ для использования NestorBasic]]^^ |[[#f80|Функция 80]]|Узнать или задать количество сегментов выделенных для NestorBASIC| ^[[#n1011|Функции для взаимодействия с NestorMan и InterNestor Suite/Lite]]^^ |[[#f81|Функция 81]]|Проверка присутствия NestorMan и InterNestor Suite в ОЗУ| |[[#f82|Функция 82]]|Выполнить функцию NestorMan| |[[#f83|Функция 83]]|Передача блока данных из сегмента NestorMan в сегмент NestorBASIC| |[[#f84|Функция 84]]|Передача блока данных из сегмента NestorBASIC в сегмент NestorMan| |[[#f85|Функция 85]]|Вызов процедуры InterNestor Suite| |[[#f86|Функция 86]]|Вызов процедуры InterNestor Lite| {{anchor:a2}} ====== Приложение 2 ====== **Доступные пользователю внутренние процедуры и переменные NestorBASIC** Когда выполняются подпрограммы пользователя в кодах или пользовательские прерывания, сегмент NestorBASIC остается подключенным в страницу 1. В его начале есть таблица, содержащая переходы на некоторые внутренние процедуры NestorBASIC, а также его внутренние переменные, которые могут быть полезны для подпрограмм пользователя. В этом разделе описывается расположение и назначение этих подпрограмм и переменных. Все эти процедуры не меняют состояние прерываний, кроме [[#PUTSLOT0]], возврат из которой происходит с запрещенными прерываниями. **К сведению**: Логический сегмент 255 всегда ссылается на память, подключенную во 2 и 3 страницы на момент обращения к данному сегменту. Когда выполняется подпрограмма пользователя в машинных кодах, или подпрограмма прерывания пользователя, страница 2 содержит НЕ сегмент основного ОЗУ [[msx:basic:|]], а сегмент самой подпрограммы. Чтобы действительно сконвертировать сегмент 255 в соответствующий сегмент [[msx:basic:|]], нужно выполнить следующее: ld hl,address call CHKSLFF cp 3 jr z,OKFF ld a,2 OKFF: ; Внимание: упомянутые в этом разделе переменные и области данных предназначены только для чтения. Их изменение может привести к непредсказуемым результатам. Содержимое таблицы представлено ниже: **&H4100** \\ Идентификационная строка "NestorBASIC x.xx" **&H4110: TABSEGS** \\ Указатель на таблицу сегментов. Формат этой таблицы следующий: |<50% 20% 80%>| |-2|Максимальное число сегментов, доступных для аллоцирования NestorBASIC (неизменное значение под [[msx:dos:#v1x|MSX-DOS 1]]; под [[msx:dos2:|]] это значение действительно лишь сразу после загрузки NestorBASIC, и может меняться после)| |-1|Количество аллоцированных сегментов (аналогично P(0), возвращаемому функциями 1 и 80)| |+0|Слот логического сегмента 0| |+1|Физический сегмент логического сегмента 0| |+2|Слот логического сегмента 1| |+3|Физический сегмент логического сегмента 1| |...|| |+492|Слот логического сегмента 246| |+493|Физический сегмент логического сегмента 246| **&H4112: INT_DATA** \\ Содержит информацию об активных прерываниях NestorBASIC: |<50% 20% 80%>| |бит 0 = 1|Пользовательское прерывание активно| |бит 1 = 1|Звуковой эффект активен| |бит 2 = 1|Музыка Moonblaster 1.4 воспроизводится| |бит 3 = 1|Музыка Moonblaster Wave воспроизводится| {{anchor:putslot0}} **&H4113: PUTSLOT0** \\ Подключает слот к странице 0 без использования ENASLT. После возврата из данной процедуры прерывания запрещены. |<50% 20% 80%>| |Вход|A = Номер слота, который надо подключить| |Выход| — | |Регистры|AF| **&H4116: CHKSLE** \\ Проверяет, существует ли логический сегмент. НЕ распознает как действительные, сегменты, соответствующие VRAM, а также 255–й. |<50% 20% 80%>| |Вход|A = Логический сегмент| |Выход|Cy= 1 — Логический сегмент существует \\ Cy= 0 — Логический сегмент не существует| |Регистры|F| **&H4119: CHKSLFF** \\ Проверяет, является ли логический сегмент 255–м, и в этом случае преобразует его в соответствующий сегмент (текущий сегмент страницы 2 если HL<&HC000, сегмент 3 если HL>=&HC000) |<50% 20% 80%>| |Вход| A = Логический сегмент \\ HL = Адрес| |Выход|A = Преобразованный номер сегмента, если это был 255–й, иначе — не измененный| |Регистры|F| **&H411C: CHKSLV** \\ Проверяет, является ли логический сегмент сегментом VRAM, и если да, то преобразует его в соответствующий адрес VRAM. |<50% 20% 80%>| |Вход|A = Логический сегмент \\ HL = Адрес| |Выход|Если является VRAM: \\ A = Блок VRAM \\ HL = Адрес VRAM \\ Cy = 1 \\ Если не является VRAM: \\ A, HL неизменны \\ Cy = 0| |Регистры| — | **&H411F: VTOSL** \\ Преобразует адрес VRAM в соответствующий ему логический сегмент. |<50% 20% 80%>| |Вход|A = Блок VRAM \\ HL = Адрес VRAM| |Выход|A = Соответствующий логический сегмент \\ HL = Соответствующий адрес ОЗУ \\ Cy = 1 — на входе A=1, но только 64K VRAM присутствует| |Регистры|F| **&H4122: GET_SF** \\ Получить физический сегмент и слот, соответствующие логическому сегменту. |<50% 20% 80%>| |Вход|A = Логический сегмент| |Выход|A = Физический сегмент \\ B = Слот (255 — Логический сегмент не существует)| |Регистры| — | **&H4125: GET_SLT** Узнать слот, подключенный в страницу 1 или 2. |<50% 20% 80%>| |Вход|A = Страница (1 или 2)| |Выход|B = Слот| |Регистры|F, C| **&H4128: READ_SL** \\ Прочесть один байт из логического сегмента. |<50% 20% 80%>| |Вход|A = Логический сегмент \\ HL = Адрес (0—&H3FFF)| |Выход|A = Прочитанный байт| |Регистры|F, AF'| **&H412B: WRITE_SL** \\ Записать байт в логический сегмент |<50% 20% 80%>| |Вход|A = Логический сегмент \\ E = Записываемый байт \\ HL = Адрес (0—&H3FFF)| |Выход| — | |Регистры|F, AF'| **&H412E: LDIRSS** \\ Осуществляет копирование данных из одного логического сегмента в другой. Распознает логический сегмент 255 и сегменты VRAM. Возвращается с [[msx:bios|BIOS]] подключенным в страницу 0. Не проверяет случаи, когда BC>&H4000. |<50% 20% 80%>| |Вход|IXh = Логический сегмент источника \\ IXl = Логический сегмент назначения \\ HL = Адрес источника (0..&HFFF) \\ DE = Адрес назначения (0..&HFFF) \\ BC = Длинна (0..&H3FFF)| |Выход|A = 0 — Пересылка осуществлена \\ A <> 0 — Один из логических сегментов не существует| |Регистры|Все| **&H4131: CHKBV** \\ Проверяет, существует ли адрес VRAM. |<50% 20% 80%>| |Вход|A = Блок VRAM (0 или 1, нижние или верхние 64K)| |Выход|Cy = 1 — Такого адреса не существует \\ (A = 1, но у компьютера только 64K VRAM)| |Регистры| — | **&H4134: SET_RD** \\ Подготавливает VDP к чтению VRAM. |<50% 20% 80%>| |Вход|HL = Адрес VRAM, младшие 16 бит \\ CY = Адрес VRAM, 17–й бит| |Выход| — | |Регистры|AF, HL| **&H4137: SET_WR** \\ Подготавливает VDP к записи в VRAM. |<50% 20% 80%>| |Вход|HL = Адрес VRAM, младшие 16 бит \\ CY = Адрес VRAM, 17–й бит| |Выход| — | |Регистры|AF, HL| **&H413A: LDIRVR** \\ Копирует блок данных из VRAM в RAM. |<50% 20% 80%>| |Вход|Адрес VRAM, заданный с помощью SET_RD \\ DE = Адрес назначения в RAM \\ BC = Длина| |Выход|DE = Адрес конца блока +1| |Регистры|AF| **&H413D: LDIRRV** \\ Копирует блок данных из RAM в VRAM. |<50% 20% 80%>| |Вход|Адрес VRAM, заданный с помощью SET_WR \\ HL = Адрес источника в RAM \\ BC = Длина| |Выход|HL = Адрес конца блока +1| |Регистры|AF| **&H4140: LDIRVV** \\ Копирует блок данных из VRAM в VRAM через буфер в RAM. |<50% 20% 80%>| |Вход|HL = Источник, младшие 16 бит \\ DE = Назначение, младшие 16 бит \\ BC = Длина \\ A = %000000 Н И, бит 17 Источника и Назначения \\ IX = Буфер в ОЗУ размером как минимум BC байт| |Выход| — | |Регистры|AF, HL, DE| **&H4143: FILLVR** \\ Заполняет область VRAM байтом. |<50% 20% 80%>| |Вход|Начальный адрес установлен посредством SET_WR \\ BC = Длина \\ A = Записываемый байт| |Выход| — | |Регистры| — | **&H4146: BLK_CLS** \\ Очищает область VRAM предназначенную для режима мигания (SCREEN 0 "blink" mode). |<50% 20% 80%>| |Вход| — | |Выход| — | |Регистры|AF| **&H4149: BLK_COL** \\ Устанавливает цвета режима мигания. |<50% 20% 80%>| |Вход|A = Цвет "мигнувшего" текста + 16* цвет "мигнувшего" фона| |Выход| — | |Регистры|A| **&H414C: BLK_TIM** \\ Устанавливает временные интервалы режима мигания. |<50% 20% 80%>| |Вход|A = Время ВКЛ + 16* время ВЫКЛ| |Выход| — | |Регистры|A| **&H414F: BLK_ON** \\ Создание мигающего блока. |<50% 20% 80%>| |Вход|HL = XXYY \\ B = Размер X \\ C = Размер Y| |Выход|L = YY последней строки + 1 \\ H не изменяется| |Регистры|AF| **&H4152: BLK_OF** Удаление мигающего блока. |<50% 20% 80%>| |Вход|HL = XXYY \\ B = Размер X \\ C = Размер Y| |Выход|L = YY последней строки + 1 \\ H = не изменяется| |Регистры|AF| **&H4155: C_BLKAD** \\ Вычисление адреса VRAM, соответствующего заданным координатам мигающего блока. |<50% 20% 80%>| |Вход|HL = XXYY| |Выход|HL = Адрес VRAM| |Регистры|AF| **&H4158: C_STBT** \\ Вычисление бита, соответствующего заданным координатам мигающего блока. |<50% 20% 80%>| |Вход|A = Координата X| |Выход|A = Бит, установленный в 1| |Регистры|F| **&H415B: GINFOUS** \\ Выдает информацию о прерывании пользователя. |<50% 20% 80%>| |Вход| — | |Выход|A = Сегмент \\ HL = Адрес| **&H415E: GINFOSFX** \\ Выдает информацию о звуковых эффектах PSG |<50% 20% 80%>| |Вход|A = Новая максимальная громкость (-1 чтобы оставить без изменений)| |Выход|A = Сегмент воспроизведения эффектов \\ HL = Адрес воспроизведения эффектов \\ B = Номер эффекта, который звучит, или последнего, который звучал \\ C = Приоритет эффекта, который звучит, или последнего, который звучал \\ D = Наибольший номер эффекта, который существует \\ E = Максимальная громкость| {{anchor:ginfomus}} **&H4161: GINFOMUS** \\ Выдает информацию о музыке, которая проигрывается, и о присутствии плеера Moonblaster. |<50% 20% 80%>| |Вход| — | |Выход|Cy = 1 -> Ни один плеер не загружен, остальные результаты не действительны. \\ Cy = 0 -> Плеер загружен. \\ Остальные результаты действительны если проигрывается музыка (проверьте INT_DATA). \\ \\ A = Логический сегмент музыки, которая воспроизводится \\ HL = Адрес начала музыки, которая воспроизводится \\ \\ B = Присутствующие звуковые устройства: \\ bit 0 = 1 -> [[msx:music:|]] найден \\ bit 1 = 1 -> [[msx:audio|]] найден \\ bit 2 = 2 -> OPL4 найден \\ \\ C = Активные звуковые устройства: \\ bit 0 = 1 -> [[msx:music:|]] активен \\ bit 1 = 1 -> [[msx:audio|]] активен \\ bit 2 = 2 -> OPL4 активен \\ \\ D = Текущая позиция \\ \\ E = Текущий шаг (от 0 до 15) \\ IXl= 255 если музыка поставлена на паузу| **&H4164: REPTYPE** \\ Байт информации, содержащий тип проигрывателя музыки, который загружен: * 0: Проигрыватель MoonBlaster 1.4 * 1: Проигрыватель MoonBlaster Wave Внимание: прежде чем обращаться к данной информации, необходимо выяснить, загружен ли хоть один плеер. Это можно сделать с помощью функции [[#ginfomus|GINFOMUS (&H4161)]]. **&H4165: GETF01** |<50% 20% 80%>| |Вход| — | |Выход| — | Эта процедура копирует содержимое строковых массивов F$(0) y F$(1) в два буфера NestorBASIC, находящихся в странице 3; адреса этих буферов указаны в переменных F0BUFADD и F1BUFADD, упоминаемых позже. Копируется только первые 80 символов строк. В конце их добавляется символ 0. **&H4168: SETF0** \\ **&H416B: SETF1** |<50% 20% 80%>| |Вход| — | |Выход| — | Эти процедуры заносят в строковые массивы F$(0) y F$(1), соответственно, содержимое двух внутренних буферов NestorBASIC, находящихся в странице 3; адреса этих буферов указаны в переменных F0BUFADD и F1BUFADD, упоминаемых позже. Строки должны оканчиваться символом 0 в буферах, и их длина должна быть не более 80 знаков; если они больше, то только первые 80 знаков будут занесены. **&H416E: F0BUFADD** \\ **&H4170: F1BUFADD** \\ Эти внутренние переменные содержат адреса буферов в странице 3, которые используются в качестве приемника процедурой GETF01, и в качестве источника процедурами SETF0 и SETF1. Эти буферы имеют размер 80 байт каждый. **&H4172: SL_2** \\ Номер логического сегмента, подключенного в страницу 2 (то есть, номер логического сегмента, в котором находится программа, читающая эту переменную). **&H4173: NMAN_SL4** \\ Номер сегмента [[msx:nestorman:|]], соответствующего сегменту 4 NestorBASIC. **&H4174: INS_SL1** **&H4175: INS_SL2** **&H4176: INS_SL3** **&H4177: INS_SL4** \\ Номера сегментов [[msx:nestorman:|]] модулей [[msx:internestor_suite:|]] с 1 по 4, соответственно. {{anchor:a3}} ====== Приложение 3 ====== **Прерывания на MSX Turbo-R** NestorBASIC отлично работает на любом MSX 2/2+/Turbo-R, но может вызвать проблемы с прерываниями, если исполняется на Turbo-R в режиме [[msx:dos:#v1x|MSX-DOS 1]], особенно если используется внешнее расширение ОЗУ. Это связано с тем, что перед выполнением прерывания, NestorBASIC должен убедится, что сегмент подключен в страницу 1, и в режиме [[msx:dos:#v1x|MSX-DOS 1]] это может быть сделано только инструкцией ''IN A,(&HFD)'', которая на Turbo-R работает не совсем так, как на MSX2/2+. Поэтому, если Вы собираетесь использовать пользовательские прерывания или звуковые эффекты в программе, которая использует NestorBASIC, самое лучшее будет проверять — является ли компьютер Turbo-R (если ''PEEK(&H2D)=3''), и не работает ли в режиме [[msx:dos:#v1x|MSX-DOS 1]] (это можно сделать [[#f1|функцией 1]]), и в этом случае сообщить пользователю, что требуется загрузиться в режиме [[msx:dos2:|]]. {{anchor:a4}} ====== Приложение 4 ====== **Условия использования** NestorBASIC это бесплатная программа, или, на профессиональном языке, freeware. Тем не менее, есть несколько условий для использования его в ваших программах: * Где-нибудь в программе (при загрузке, в разделе "О программе", и т.п.) должно появляться упоминание об использовании NestorBASIC, а также его версия (чтобы узнать версию NestorBASIC, используйте [[#f1|функцию 1]]). * Если программа предназначена не исключительно для личного пользования автора (то есть, если она будет распространяться бесплатно или за плату), нужно предоставить мне ее копию. Если у вас есть предложения, вопросы или комментарии относительно NestorBASIC, вы можете связаться со мной по адресу . Использование звуковых эффектов, созданных в редакторе SEE, обусловлено своими собственными требованиями. Если вы собираетесь продавать вашу программу за более чем 15 гульденов, вы должны будете заплатить небольшую сумму авторам, как максимум 25 гульденов. Для конкретных деталей касательно SEE свяжитесь с Fuzzy Logic: R. v/d Meulen A. v/d Wal Lijsterstraat 25 Tormentil 15 8917 CX Leeuwarden 8445 RR Heerenveen Holland. Holland. ====== Ссылки ====== [[msxorg>wiki/Nestor-BASIC|NestorBASIC]] [[http://mus.msx.click/index.php?title=MBWAVE_DISKMENU_EN|MBWAVE DISKMENU EN - MSX MUSIC WIKI]] {{tag>MSX BASIC X-BASIC}}