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

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


Invalid size representation "1.6567383e-5"
msx:nestor_basic:nestor_basic

NestorBASIC

Это статья написана на основе документации User's manual in english, version 1.11, оригинал
Автор: Nestor Soriano (Konami Man), Декабрь 2004

Nestor Soriano также является автором Nextor

Официальная страница NestorBASIC

Перевод документации выполнил: ATroubleshooter, 2021–2023
Перевод документации NestorBASIC version 1.11 на русский

Оформление и корректура: Алексей Сысоев aka GreyWolf.

Содержание

1. Что такое NestorBASIC ?

NestorBASIC — это набор подпрограмм(функций, процедур) в машинном коде, интегрированных в один файл, предназначенных для использования в программах на Бейсике. NestorBASIC обеспечивает, без утраты совместимости с MSX X-BASIC, следующую функциональность:

  • Полный доступ ко всей страничной оперативной памяти компьютера(всей памяти, в случае MSX-DOS, всей свободной памяти в случае MSX-DOS 2), вплоть до 4 Мб.
  • Доступ ко всей видеопамяти(VRAM), с возможностью пересылки блоков данных как в пределах VRAM, так и между VRAM и RAM.
  • Размещение программ MSX BASIC в страничной памяти, с возможностью выполнять переход из одной программы в другую с сохранением переменных.
  • Доступ к файлам на диске и непосредственно к физическим секторам, с возможностью чтения/записи напрямую в/из страничной RAM и VRAM. Поиск файлов, работа с директориями.
  • Сжатие и распаковка графики.
  • Проигрывание Moonblaster-музыки. Подгрузка samplekit'ов.
  • Воспроизведение звуковых эффектов на PSG(AY-3-8910).
  • Вызов подпрограмм в машинном коде, находящихся в BIOS, Sub-BIOS, в основной области памяти MSX BASIC, рабочей области системы, или в сегменте страничного ОЗУ.
  • Вызов функций NestorMan, процедур InterNestor Suite и InterNestor Lite.

Все имеющиеся функции доступны через один единственный USR и массив целочисленных параметров, следовательно они полностью совместимы с MSX X-BASIC.

Собственно, сам компилятор MSX X-BASIC содержится в файле NBASIC.BIN, и автоматически загружается при резидентной установке NestorBASIC.

NestorBASIC загружается в сегмент ОЗУ, не используемый MSX BASIC, так что нужен лишь небольшой объем основной памяти MSX BASIC (примерно 500 байт) для программы перехода. Остальная основная память MSX BASIC свободна для программы на Бейсике.

2. Системные требования. Загрузка NestorBASIC

NestorBASIC работает на любой MSX2/2+/Turbo-R с как минимум 128 кБ страничной памяти. В случае с MSX-DOS 2 нужен хотя бы один свободный сегмент ОЗУ в первичном маппере (два, если собираетесь использовать проигрыватели музыки. См. раздел 8 для подробностей).

Файл Размер
(байт)
Контрольная сумма
MD5
Описание
NestorBASIC 1.115853942f1a7d5d3fe2281c743f4283fc4f4a9оригинал

Этот архив содержит все исходные файлы для сборки.

Для сборки из исходного текста рекомендуется использовать среду разработки Compass, либо кросс-ассемблер SjAsm на ПК.

Для загрузки NestorBASIC, просто выполните в MSX BASIC команду:

BLOAD"NBASIC.BIN",R

Также можно выполнить вызов из файла автозапуска:

AUTOEXEC.BAS
10 BLOAD"NBASIC.BIN",R:NEW

Ни предварительных, ни последующих команд CLEAR и DEFUSR не требуется. Если все прошло без ошибок, мы получаем следующее:

  1. NestorBASIC и MSX X-BASIC загружены, каждый в свой сегмент ОЗУ, и готовы к работе.
  2. Размер свободной основной памяти MSX BASIC уменьшился примерно на 500 байт, которые были заняты программой, осуществляющей переход в сегмент NestorBASIC.
  3. Первый USR [USR0(параметр) или просто USR(параметр)] указывает на вышеупомянутую программу перехода — это hook для вызова функций NestorBASIC.
  4. Создан целочисленный массив параметров P. Этот массив используется для передачи параметров в функции NestorBASIC и приёма из них результатов, за исключением кодов ошибок. Коды ошибок возвращаются командой USR (функции для работы с файлами и функции обработки строк требуют собственный строковый массив, который нужно объявлять отдельно. См. раздел 4 для подробностей). Первые пять элементов P инициализированы следующим образом:
P(0)Количество доступных сегментов памяти, или код ошибки
P(1)Мажорная версия NestorBASIC
P(2)Минорная версия NestorBASIC, в формате BCD (должна показываться в шестнадцатеричном формате)
P(3)Мажорная версия MSX-DOS
P(4)Минорная версия MSX-DOS, в формате BCD (должна показываться в шестнадцатеричном формате)

Число доступных сегментов ОЗУ всегда будет как минимум 5. Меньшее значение в P(0) будет отражать код ошибки, возникшей при резидентной установке NestorBASIC:

0Компьютер не имеет страничной памяти, или в нем только 64кБ страничного ОЗУ
1Дисковая ошибка при чтении NestorBASIC или MSX X-BASIC из файла NBASIC.BIN
2Нет свободных сегментов в первичном маппере. Эта ошибка может появиться только под MSX-DOS 2)
3NestorBASIC уже установлен. Все переменные были переинициализированы
4Не определено в этой версии

После резидентной загрузки NestorBASIC можно резервировать память для других резидентных подпрограмм в обычном порядке, т. е. использовать команду CLEAR для установки начала зарезервированной области.

Тем не менее, в связи с тем, что NestorBASIC производит переключения слотов/сегментов в странице 2, и интерпретатор MSX BASIC располагает стек в области памяти ниже области строковых переменных и области, зарезервированной для пользователя, есть нижний предел для адреса, устанавливаемого командой CLEAR. А конкретно, нельзя зарезервировать память с адреса меньше, чем определяется данной формулой:

&HC000 + (MAXFILES+1)*267 + FRE("") + 100

Также, помните, что команда CLEAR, как и загрузка/очистка/модификация программы на MSX BASIC стирает все переменные. В этом случае, массив P должен быть переопределён командой DEFINT P:DIM P(15), и это должно быть сделано вне блоков компиляции (далее — турбо-блоков). Также, должен быть переопределен массив F, если требуется (см. раздел 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 не заняты.

3. Логические сегменты

3.1. Что такое логический сегмент?

Страничное ОЗУ компьютеров MSX организовано в сегменты по 16 кБ. Каждый слот ОЗУ содержит определённое число S сегментов (нумеруемых от 0 до S-1), доступных, когда они подключены в адресное пространство активного слота памяти, что контролируется через порты с &HFC по &HFF.

При загрузке NestorBASIC, все имеющиеся слоты сканируются на наличие ОЗУ (всей памяти в случае MSX-DOS, всей свободной памяти в случае MSX-DOS 2), и строится таблица сегментов. В этой таблице, все найденные сегменты регистрируются в пары слот-сегмент (под MSX-DOS 2, сегменты сначала выделяются). NestorBASIC идентифицирует каждую из этих пар по порядковому номеру в таблице. Этот номер называется номером логического сегмента, и позволяет пользователю оперировать всей доступной памятью в последовательном виде, не заботясь ни о номерах слотов, ни о номерах физических сегментов, в которых она находится. Например, представим MSX с 128 кБ внутренней RAM (8 сегментов) и маппер на 1024 кБ (64 сегмента) во внешнем слоте. Тогда, после инициализации NestorBASIC, в случае MSX-DOS, пользователю будет доступно 72 логических сегмента, под номерами от 0 до 71, и достаточно указать этот номер в соответствующих функциях NestorBASIC для их использования. Номера физических слотов и сегментов уже не потребуются.

Адресное пространство логического сегмента (далее — просто «сегмента») от &H0000 до &H3FFF. Если заданы более высокие адреса при вызове функций NestorBASIC, они будут преобразованы. То есть, адреса &H4000–&H7FFF, &H8000–&HBFFF и &HC000–&HFFFF эквивалентны &H0000–&H3FFF при доступе к сегментам ОЗУ через NestorBASIC.

Все сегменты доступны для чтения и записи, но есть важные ограничения по отношению к первым шести:

  1. Сегмент 0 содержит собственно NestorBASIC, и лишь небольшая область ОЗУ остаётся доступной для пользователя в конце него. Используйте функцию 1 чтобы получить начальный адрес этой области (описание функции см. в разделе 10).
  2. Сегмент 1 содержит компилятор MSX X-BASIC. Можно перезаписать этот сегмент только в том случае, если Вы не собираетесь использовать компилятор.
  3. Сегмент 2 всегда подключён к 2 странице (адреса &H8000–&HBFFF), и содержит исполняемую программу на MSX BASIC и часть её переменных.
  4. Сегмент 3 всегда подключён к странице 3 (адреса &HC000–&HFFFF), и содержит рабочую область системы и часть переменных программы на MSX BASIC. Будьте внимательны при записи сюда.
  5. Сегмент 4 используется как служебный буфер некоторыми функциями NestorBASIC. Вы можете использовать этот сегмент для ваших данных, если Вы не обращаетесь к этим функциям NestorBASIC. См. раздел 10 или приложение 1 чтобы узнать, какие функции используют этот сегмент.
  6. Сегмент 5, если он есть, изначально свободен, и не используется NestorBASIC.

Но если используются музыкальные плееры, при инициализации они занимают этот сегмент. См. раздел 8 для подробностей.

Все оставшиеся сегменты — в полном распоряжении программиста.

Внимание: логические сегменты 2 и 4 поменялись ролями при переходе с версии 0.07 на версию 1.00 NestorBASIC. В версии 0.07 и ранее, сегмент 2 был служебным буфером NestorBASIC, а сегмент 4 соответствовал странице 2.

При использовании функций обмена блоками данных, нужно быть осторожным, чтобы сумма адреса назначения и длины пересылаемого блока не превысила адрес &H3FFF (например, не пытайтесь переслать &H2000 байт указывая адрес &H3000 как адрес назначения). В таком случае, сегмент 0 или сегмент 3 будут перезаписаны, и результат будет непредсказуем.

Внимание: с помощью функции 80 можно указать NestorBASIC зарезервировать меньше сегментов памяти, чем суммарно доступно. Это полезно под MSX-DOS 2, когда одновременно используются другие резидентные программы, требующие выделения памяти (например, RAM-диск или NestorMan). Описание функций см. в разделе 10.

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. Эти функции позволяют пересылать данные VRAMRAM и VRAM ↔ файл.

Внимание: сегменты VRAM могут использоваться — как и обычные сегменты RAM — для размещения данных и программ на MSX BASIC, а также для блоковых операций обмена с диском и сегментами RAM. Но учтите, что сегменты VRAM не могут быть использованы для:

  • Сжатия/распаковки графики
  • Исполнения программ в машинном коде
  • Исполнения прерываний, определяемых пользователем.
  • Воспроизведения звуковых эффектов на PSG(AY-3-8910)
  • Воспроизведения музыки

Если Вы попытаетесь использовать сегменты VRAM для какой-то из этих целей, функция вернёт ошибку «несуществующий сегмент».

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)

3.4. Карта сегментов

Резюмируя данный раздел, предоставим весь список имеющихся сегментов и их описание. S — это количество сегментов, возвращаемое в P(0) при резидентной загрузке NestorBASIC или при вызове функции USR0(1)

Назначение
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. См. раздел 8.
VRAMVRAM 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)

3.5. Ошибки

Все функции доступа к RAM и/или VRAM возвращают код ошибки -1 в следующих случаях:

  • указан номер отсутствующего сегмента памяти;
  • попытка доступа к адресу VRAM выше &HFFFF в компьютерах с 64 кБ VRAM;
  • указан сегмент VRAM или 255-й сегмент в функциях, которые поддерживают только обычные сегменты RAM.

4. Доступ к диску

NestorBASIC включает функции для работы с файлами на диске и доступа к другим возможностям MSX-DOS, а именно:

  • создание/удаление/переименование/поиск файлов;
  • чтение/запись файлов в/из любого сегмента или области VRAM;
  • чтение/запись секторов в/из любого сегмента или области VRAM;
  • определение ёмкости диска, свободного пространства.

Функции, доступные только под MSX-DOS 2:

  • перемещение файлов, чтение/установка атрибутов файла;
  • получение/смена текущего рабочего диска/каталога (директории);
  • определение ёмкости/создание RAM-диска.

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

ВАЖНО: Строковые переменные, определенные вне турбо-блока, равно как и другие переменные, не передаются в турбо–блок, и восстанавливаются после его завершения!

Пример.

41.bas
10 A$="Outside"
20 _TURBO ON
30 A$="Inside":PRINT A$
40 _TURBO OFF
50 PRINT A$
run
Inside
Outside

Запустить в 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)… как обычно.

4.2. Ошибки

Помимо ошибки -1, описанной в разделе 3, функции работы с диском имеют собственные коды ошибок.

Следующие ошибки могут появиться только под MSX-DOS:

1Единый код ошибки MSX-DOS. Он может быть вызван следующими причинами:
  • Файл не найден.
  • Неверное имя файла.
  • Файл уже существует (при переименовании).
  • Неверное имя диска (когда в составе пути файла).
  • Достигнут конец файла при чтении из файла.
  • Диск полон.
  • Корневая директория полна.
  • Функция не доступна под MSX-DOS.

Под MSX-DOS 2, каждая из вышеперечисленных ошибок имеет свой собственный код, никогда не равный 1.

2Неверный номер файла (нет открытых файлов с таким номером).
3Слишком много открытых файлов. Максимальное число одновременно открытых файлов можно узнать посредством функции 1.

Следующие ошибки одинаковы под MSX-DOS и MSX-DOS 2, и имеют те же коды ошибок, что и их эквиваленты в MSX BASIC:

60Неисправная FAT
62Неверный диск (при изменении рабочего диска).
68Диск защищен от записи.
69Физическая ошибка диска.
70Диск отсутствует.

Специфичные для MSX-DOS 2, ошибки:

222Не достаточно свободной памяти для создания RAM-диска для открытия файла.
219Неверный диск (будучи частью пути или имени файла).
218Неправильное имя файла.
217Неправильный путь.
215Файл не найден.
214Каталог (директория) не найден.
213Корневая директория заполнена.
212Диск заполнен.
211Файл уже существует (при переименовании или перемещении файла).
210Некорректная операция перемещения директорий (каталог не может быть перемещён в один из своих подкаталогов).
209Файл только для чтения (при попытке записи в файл).
208Каталог не пуст (при попытке удаления каталога).
207Некорректные атрибуты (при установке атрибутов файла/директории).
206Некорректная операция с «.» или «..»
205Существует системный файл с таким именем(при создании файла, любой существующий файл с таким именем автоматически удаляется, если только у него не установлен атрибут «системный»).
204Директория с таким именем уже существует (аналогично случаю с системными файлами).
203Файл с таким именем уже существует (при создании каталога).
202Файл открыт (при удалении, переименовании или перемещении файла, или при изменении атрибутов с прямым указанием имени файла).
199Достигнут конец файла (при чтении из файла).
196Слишком много открытых файлов (при открытии файла).
195Неправильный номер файла (больше 63).
194Неверный номер файла (не принадлежит ни одному открытому файлу).
188RAM-диск уже существует (при создании RAM-диска).
187RAM-диск не существует (при удалении RAM-диска).

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.

5.1 Ошибки

Функции компрессии/декомпрессии графики могут возвращать следующие коды ошибок:

-1Ошибка при сжатии или распаковке. Задан несуществующий сегмент, сегмент VRAM или 255-й. Также, эта ошибка появляется при указании некорректного адреса VRAM в любом из входных параметров.
5Ошибка при упаковке. Недостаточно сегментов для сжатия всего изображения.
6Ошибка при распаковке. Найдены некорректные данные, или закончились сегменты, прежде чем встретился маркер окончания данных.

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, которая позволяет сохранить в файл активную программу с таким заголовком. В дальнейшем, просто загрузите этот файл в какой-нибудь сегмент с помощью дисковой функции, и программа готова к использованию — её можно актуализировать или выполнить в любой момент.

6.1 Ошибки

Очевидно, что если исполняется команда или строка, следующая за USR-функцией, которая актуализирует или запускает другую программу на BASIC, то это означает, что мы находимся в состоянии ошибки. Возможна одна из двух ошибок:

-1Заданный сегмент не существует. Эти функции поддерживают сегменты VRAM, но не сегмент 255.
-2Памяти MSX-BASIC не достаточно для новой программы и переменных. Случается, если актуализируемая/запускаемая программа больше, чем исходная.

7. Различные прочие функции

В этой группе собраны функции, предназначенные для:

  • Вызова подпрограмм в машинном коде, находящихся в BIOS, Sub-BIOS, в основной памяти Бейсик, рабочей области системы или в сегменте ОЗУ (так называемые «пользовательские подпрограммы»).
  • Размещения строковых переменных в сегментах RAM и извлечения их оттуда.
  • Вывода на экран строковых переменных в графическом режиме.
  • Управления миганием (blink mode) в SCREEN 0
  • Назначения пользовательских прерываний (программы в машинном коде, находящиеся в сегменте RAM, выполняемые каждое прерывание по таймеру 50/60 Гц).
  • Воспроизведения звуковых эффектов на PSG(AY-3-8910), созданных в SEE версий 3.xx

Некоторые из этих функций требуют строковый массив F$ для передачи параметров и возврата результатов, в дополнение к целочисленному массиву P. Больше подробностей о массиве F$ см. в разделе 4.

Некоторые из внутренних процедур NestorBASIC могут вызываться из других машинных подпрограмм пользователя и использоваться прерыванием, определяемым пользователем. См. приложение 2 для детального описания использования этих процедур.

Редактор SEE (sound effects editor) для создания звуковых эффектов под PSG был разработан группой Fuzzy Logic, и использование звуковых эффектов, сделанных в этом редакторе, в коммерческих продуктах подразумевает отчисление небольшой суммы авторам. Больше деталей в приложении 4.

8. Воспроизведение музыки

8.1. Инициализация музыкального плеера

NestorBASIC включает музыкальные проигрыватели Moonblaster 1.4 и Moonblaster Wave для MoonSound версии 1.05

Эти плееры не загружаются автоматически вместе с NestorBASIC: вследствие своего большого размера, они не помещаются в сегмент ОЗУ NestorBASIC, и должны загружаться в отдельный сегмент. Поэтому, чтобы использовать плеер, его нужно загружать директивно. Одновременно может быть загружен лишь один плеер.

Функция 71 загружает и инициализирует желаемый плеер, оставляя его готовым к работе. Эта функция проверяет наличие 5-го сегмента и принадлежность его к первичному мапперу: если это так, то плеер загружается в этот сегмент, после чего сегмент становится не доступен для программы пользователя. Если сегмент 5 не существует, или подключён не к первичному мапперу, плеер не будет загружен, и функция выдаст ошибку.

Файл NBASIC.BIN содержит два варианта проигрывателя Moonblaster Wave: один для MSX2 / 2+ и Turbo-R в режиме Z80, а другой для Turbo-R в режиме R800. Если компьютер это Turbo-R, то NestorBASIC определяет, какой вариант загружать, в соответствии с тем, в каком режиме работает процессор в момент вызова функции 71. Заметьте, что если произведено переключение режима процессора, эту функцию нужно вызвать заново, чтобы загрузить соответствующий плеер: вариант для Z80 не работает в режиме R800, а вариант для R800 привносит ненужное замедление системы в режиме Z80.

После того, как плеер загружен, происходит поиск звуковых устройств, и все найденные помечаются как активные. Подробности о включении и отключении звуковых устройств см. в описании функции 73.

8.2. Возможности плеера

Как только плеер загружен, он может использоваться функциями NestorBASIC для:

  • Начала проигрывания музыки, предварительно загруженной в сегмент RAM (сегменты VRAM не поддерживаются).
  • Остановки воспроизведения музыки.
  • Паузы/продолжения воспроизведения музыки.
  • Постепенного затухания музыки, с выбором скорости затухания.
  • Получения информации о воспроизводимой музыке (сегмент и начальный адрес, по которому она находится, название мелодии, набор сэмплов (samplekit) или набор PCM-инструментов (wavekit), текущая позиция и темп).
  • Получения сведений о обнаруженных звуковых устройствах.
  • Отключения звуковых устройств, чтобы они не задействовались, несмотря на то, что были обнаружены.
  • Загрузки samplekit-а музыкальной композиции или wavekit-а для Moonsound из файла.

Во время проигрывания музыки, все функции NestorBASIC работают как обычно, включая проигрывание 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 байт муз. композиции, содержащие таблицу паттернов и различные указатели, должны целиком быть помещены в один, начальный сегмент.

8.3 Ошибки

Функции проигрывания музыки могут возвращать следующие коды ошибок:

7Возвращается функцией активизации аудио-чипов, функцией паузы и функцией затухания, если если какой-то из входных параметров некорректен.
12Возвращается функцией старта воспроизведения и функцией включения аудио-чипов, если плеер не загружен. Остальные функции не выдадут ошибку в этом случае, они просто не сделают ничего

Следующие ошибки могут произойти при выполнении функции запуска воспроизведения:

-1Указанный сегмент не существует, соотносится с VRAM, или это 255 сегмент.
12Плеер не загружен.
13Музыка была записана в режиме EDIT и не может быть воспроизведена (плеер Moonblaster 1.4).
По данному адресу нет композиции Moonblaster Wave, или там находится композиция Moonblaster Wave, записанная в режиме EDIT (плеер Moonblaster Wave).
14Уже проигрывается другая музыка в этот момент.

Функция загрузки wavekit для Moonsound, помимо ошибок работы с диском, может вернуть такую ошибку:

15По данному смещению в указанном файле нет wavekit для Moonblaster Wave, или там находится wavekit, сохранённый не в режиме USER.

:!: ВНИМАНИЕ: Плеер Moonblaster 1.4 не умеет различать, являются ли данные по конкретному адресу в действительности композицией Moonblaster 1.4, и лишь всецело полагается на первый байт для определения того, что это данные композиции, сохранённой в режиме EDIT. Плеер Moonblaster Wave не имеет этой проблемы.

Функция загрузки плеера выдаёт такие же коды ошибок, как и функции для работы с диском, а также код -1 — если сегмент 5 не существует или не принадлежит первичному мапперу.

ДЛЯ СПРАВКИ: Муз. композиции Moonblaster Wave могут быть сохранены в файл в режимах EDIT и USER. Файлы, сохранённые в режиме EDIT, содержат максимум информации о композиции, и могут быть воспроизведены только в самом трекере (музыкальном редакторе). Файлы, сохранённые в режиме USER, могут быть проиграны плеерами, и пригодны для встраивания в сторонние программы. Они предельно компактны, из них исключена вся избыточная информация — незадействованные в мелодии паттерны/инструменты/тоны. Названия инструментов и тонов также не сохраняются.

9. Взаимодействие с NestorMan и InterNestor Suite/Lite

MSX-DOS 2 UNAPI

NestorBASIC имеет специальные функции, которые позволяют взаимодействовать с NestorMan (резидентный динамический менеджер памяти для MSX-DOS 2), пакетом InterNestor Suite (стек TCP/IP для MSX-DOS 2) и InterNestor Lite (стек TCP/IP для MSX-DOS), если эти программы запущены. Таким образом, возможна разработка приложений на Бейсике, которые используют динамические блоки памяти и связанные списки, а также Internet–приложения. Чтобы узнать, запущен ли NestorMan и InterNestor Suite, можно воспользоваться функцией 81. Процедура проверки наличия загруженного InterNestor Lite детально описана в разделе 9.4.

ВНИМАНИЕ: NestorMan и InterNestor Suite / InterNestor Lite имеют собственную документацию, описывающую их функции и процедуры. Эти программы доступны здесь.


TCPCON, оригинал

9.1. Сегменты NestorBASIC и сегменты NestorMan

NestorMan реализует систему логических сегментов, очень похожую на ту, что применяется в NestorBASIC. Оба пространства сегментов, NestorBASIC и NestorMan, полностью независимы друг от друга, за несколькими исключениями:

  • Сегменты 0, 1, 2 и 3 являются общими для NestorBASIC и NestorMan (в документации к NestorMan эти сегменты называются «TPA segments»).
  • Если, при резидентной загрузке NestorBASIC, NestorMan запущен — тогда логический сегмент 4 NestorBASIC выделяется не с использованием механизмов MSX-DOS 2, как остальные сегменты. Вместо этого, используется функция 7 NestorMan; таким образом, 4-му сегменту NestorBASIC присваивается, в свою очередь, номер сегмента NestorMan (этот номер можно узнать посредством 81-й функции NestorBASIC). Этот сегмент зарезервирован установкой атрибута «exclusive», и поэтому не используется NestorMan для выделения блоков памяти.

Если NestorMan и/или InterNestor Suite будут использоваться вместе с NestorBASIC, рекомендуется ограничить, с помощью функции 80, количество сегментов RAM, которые будут использоваться NestorBASIC. В противном случае, NestorBASIC зарезервирует для себя все доступные сегменты, и NestorMan не сможет задействовать резервы ОЗУ (необходимые для выделения блоков памяти, создания связанных списков и для отправки/получения данных в/из Интернета).

Для вызова функций NestorMan можно использовать 82-ю функцию; или можно использовать 58-ю функцию, указав хук EXTBIO (&HFFCA) в качестве адреса перехода, занеся &H2202 в регистровую пару DE, и номер функции в регистр C. См. описание функций в разделе 10.

9.2. Обмен данными между NestorBASIC и NestorMan

При использовании NestorMan из NestorBASIC, обычно Вам придётся осуществлять передачу данных между сегментом NestorBASIC и сегментом NestorMan. Есть три способа сделать это:

  1. Если сегмент источника или назначения — это сегмент TPA (номер сегмента от 0 до 3), достаточно использовать соответствующую функцию NestorMan для передачи блока данных (функция 14), поскольку NestorMan и так видит эти сегменты.
  2. Можно использовать сегмент 4 NestorBASIC как промежуточный буфер для пересылки. Например, предположим пересылку из NestorBASIC в NestorMan. S1 это источник — сегмент NestorBASIC, S2 это назначение — сегмент NestorMan, и S3 это номер сегмента NestorMan, соответствующий 4 сегменту NestorBASIC. Тогда, сначала делается пересылка S1→4 с помощью функции NestorBASIC (функция 10), и затем делается пересылка S3→S2 с использованием функции NestorMan (функция 14).
  3. Функции 83 и 84 NestorBASIC осуществляют блочное копирование данных из сегмента NestorMan в сегмент NestorBASIC и наоборот.

Чтобы прочитать или записать единственный байт данных из/в сегмент NestorMan, проще всего использовать соответствующие функции, которые предоставляет NestorMan (функции 12 и 13).

Помните, что некоторые функции NestorBASIC используют сегмент 4 как служебный буфер для временного размещения данных. См. раздел 10 или приложение 1, чтобы узнать эти функции.

9.3. Использование InterNestor Suite

Методика, при использовании InterNestor Suite из NestorBASIC, схожа с той, что применяется для работы с NestorMan. Единственно, нужно иметь в виду следующее:

  • Функция 85 позволяет исполнять процедуры InterNestor Suite.
  • Чтобы читать и записывать данные в сегменты InterNestor Suite (константы конфигурации и переменные), сначала нужно, используя функцию 81, выяснить номера сегментов модулей InterNestor Suite (каждый модуль занимает сегмент NestorMan), а далее, использовать методы обмена данными, описанные в предыдущем разделе.
  • Процедуры InterNestor Suite для чтения/записи данных TCP или датаграмм UDP

допускают использование только сегментов TPA как источника/назначения данных или датаграмм. Для этой цели можно использовать последнюю часть сегмента NestorBASIC (сегмент 0) как временный буфер. Это свободное пространство всегда будет, как минимум, размером 600 байт, независимо от используемой версии NestorBASIC.
Этого достаточно для размещения стандартной датаграммы до 576 байт длинной (или для размещения блока данных TCP до 600 байт включительно).

Пример программы TCPCON-S.BAS (см. здесь), поставляемый с NestorBASIC, иллюстрирует использование NestorBASIC'а совместно с InterNestor Suite.

ВНИМАНИЕ: InterNestor Suite это устаревшее ПО и не рекомендуется к спользованию. Если Вам нужен рабочий стэк TCP/IP, посмотрите в сторону InterNestor Lite.

9.4. Использование InterNestor Lite

InterNestor Lite это гораздо более простая программа, чем InterNestor Suite, поэтому использовать её из NestorBASIC также проще. Предоставляется единственная функция (функция 86), которая позволяет выполнять несколько процедур из сегмента кода InterNestor Lite. Чтобы читать или писать в его сегмент данных, необходимо использовать процедуры GET_VAR, SET_VAR и COPY_DATA, которые находятся в сегменте кода.

Чтобы узнать, запущен InterNestor Lite или нет, используйте функцию 58 для вызова хука EXTBIO (адрес &HFFCA), передав A=0 и DE=&H2203. Если подпрограмма вернула A≠0, значит InterNestor Lite запущен. Больше подробностей в описании функции 86.

Многие из процедур InterNestor Lite используют адреса TPA как источник либо назначение для обмена данными с приложениями. Для таких процедур можно указать адреса выше &H8000, которые соответствуют основной памяти MSX BASIC и рабочей области системы; или адреса ниже &H4000, которые соответствуют сегменту NestorBASIC (сегмент 0).

В конце сегмента NestorBASIC есть свободная область, размер которой варьируется, в зависимости от версии NestorBASIC, но никогда не бывает меньше, чем 600 байт. Эта область может быть использована как временный буфер для обмена данными с InterNestor Lite. Другими словами, можно использовать диапазон от H3DA8 до &H3FFF в качестве TPA области — источника или приёмника для обмена данными между NestorBASIC и InterNestor Lite.

Пример программы TCPCON-L.BAS (см. здесь), поставляемый с NestorBASIC, иллюстрирует использование NestorBASIC совместно с InterNestor Suite.

9.5. Ошибки

Функция 86 (вызов процедуры InterNestor Lite) возвращает ошибку -1, если InterNestor Lite не обнаружен.

Функция 85 (вызов процедуры InterNestor Suite) возвращает ошибку -1, если InterNestor Suite не обнаружен, или если в P(0) указан недействительный номер модуля (действительны номера с 1 по 4).

Функции 83 и 84 (передача блоков данных между сегментом NestorMan и сегментом NestorBASIC) выдаёт ошибку -1, если задан несуществующий сегмент NestorMan или NestorBASIC. Эти функции могут использовать сегменты VRAM и 255-й сегмент.

Функции 80, 81 и 82 никогда не выдают ошибок.

9.6. Функции для запуска программ на BASIC

Функция 55

Запуск программы на BASIC, находящейся в сегменте (S4)

ВходP(0)Сегмент
P(1)Начальный адрес
Выход

ВАЖНО: Чтобы использовать эту функцию нужно изменить начальный адрес BASIC–программ. Детально об этом — в разделе 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 не достаточно, чтобы вместить вызываемую программу и существующие переменные вызывающей программы. Такая ситуация может возникнуть, если новая (вызываемая) программа больше, чем вызывающая программа. Но если разница в размерах не очень велика, и переменных не слишком много, вы не должны оказаться в этой ситуации.

Функция 56

Актуализация программы на BASIC, находящейся в сегменте (S4)

ВходP(0)Сегмент
P(1)Начальный адрес
Выход

ВАЖНО: Чтобы использовать эту функцию нужно изменить начальный адрес BASIC–программ. Детально об этом — в разделе 6.

Эта функция работает так же, как функция 55, с единственным отличием: после того, как новая программа помещена в основное ОЗУ MSX BASIC, и переменные размещены после неё — программа не выполняется, а интерпретатор BASIC возвращается в командный режим. За исключением этого — функционал тот же, как и причины и коды ошибок.

Функция 57

Сохранить программу на BASIC со специальным заголовком (S4)

ВходP(0)Байт, который будет сохранен в первой позиции заголовка
(Не используется NestorBASIC)
F$(0)Путь + имя файла
P(1)Начальный адрес
ВыходP(1)
  • -1 — Нет ошибок
  • <> -1 — Произошла дисковая ошибка, и файл остался открытым под данным номером; команда USR в таком случае возвращает код ошибки, как и положено.

ВАЖНО: Чтобы использовать эту функцию нужно изменить начальный адрес BASIC–программ. Детально об этом — в разделе 6.

Данная функция сохраняет активную BASIC–программу в указанный файл, с соответствующим заголовком, чтобы запускаться или активироваться с помощью функций 55 или 56 (см. функцию 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

Используя функцию 56 вместо функции 55, вы можете загружать программы, сохранённые с заголовком, для которых не имеется копий в обычном формате (LOADable).

Конечно же, вы можете также использовать обычные функции доступа к диску для сохранения программ, но тогда вам придётся создать заголовок вручную:

POKE &H8000,P(0) 'Байт не используемый NestorBASIC
POKE &H8001,PEEK(&HF6C2)
POKE &H8002,PEEK(&HF6C3)
'Сохранить начиная с &H8000 по PEEK(&H8001)+256*PEEK(&H8002) в файл

Коды ошибок, возвращаемые этой функцией — такие же, как у функций доступа к диску (см. раздел 4). Если дисковая ошибка повлекла за собой то, что файл остался открытым, тогда в P(1) будет содержаться соответствующий номер файла.

В противном случае, в P(1) будет -1.

10. Функции NestorBASIC

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, если ошибок не возникло. Коды ошибок, характерные для каждой группы функций, объяснены в соответствующих разделах.

Приложение 1 содержит полный список функций, который может быть полезен в качестве краткого справочника.

10.2. Общие функции

Функция 0

Выгрузка NestorBASIC'а из памяти (S4)

ВходP(0) = 0Не освобождать область основной памяти MSX BASIC, зарезервированную NestorBASIC
P(0) ≠ 0Освободить область основной памяти MSX BASIC, зарезервированную NestorBASIC
Выход

Эта функция выгружает NestorBASIC: высвобождает USR и, в случае MSX-DOS 2, освобождает все выделенные сегменты. Также, останавливаются все процессы, завязанные на прерывания (прерывания, определяемые пользователем, проигрывание звуковых эффектов PSG и музыки). Всегда следует выгружать NestorBASIC прежде чем вернуться в MSX-DOS; в противном случае, все зарезервированные сегменты ОЗУ не будут высвобождены, и, следовательно, не смогут быть использованы до перезагрузки компьютера.

Перед тем как выгрузить NestorBASIC, убедитесь, что не оставили открытых файлов. В противном случае, если в них осуществлялась какая-то запись, во внутренних буферах MSX-DOS могут оставаться несохраненные данные, которые будут потеряны. Вдобавок, в случае с MSX-DOS 2, не высвобождаются дескрипторы открытых файлов (file handles).

Если функции передано P(0)=0, то область основной памяти MSX BASIC, занятая обработчиком вызовов NestorBASIC (примерно 500 байт) не освобождается, что оставляет в силе схему распределения памяти, заданную командами CLEAR после загрузки NestorBASIC. Если функции передано P(0)≠0, схема распределения ОЗУ возвращается к параметрам, установленным до загрузки NestorBASIC. То есть, FRE(0) возвращает такое же значение, как до загрузки NestorBASIC. Учтите, что переменные в этом случае инициализируются.

Эта функция никогда не выдаёт ошибки.

Функция 1

Получение общей информации о NestorBASIC и конкретном логическом сегменте.

Вход 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, максимальное количество одновременно открытых файлов зависит от состояния внутренней памяти 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-DOS 2 — имя диска и каталога, заканчивающиеся «\» (например C:\UTILS\AMAZING\).

Адрес, возвращаемый в P(7) зависит от версии NestorBASIC, но всегда будет меньше или равен &H3DA8; то есть, как минимум 600 байт в конце сегмента NestorBASIC всегда будет доступно. Эта область может быть использована, например, как буфер для данных TCP или UDP-датаграмм при использовании 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.

10.3. Функции для доступа к логическим сегментам

Функция 2

Прочесть байт из сегмента

ВходP(0)Сегмент
P(1)Адрес
ВыходP(2)Полученный байт

Функция 3

Прочесть байт из сегмента с автоинкрементом адреса

ВходP(0)Сегмент
P(1)Адрес
ВыходP(2)Полученный байт
P(1) = P(1) + 1

Функция 4

Прочесть целое число (2 байта) из сегмента

ВходP(0)Сегмент
ВыходP(2)Полученное целое число

Младший байт берётся из адреса P(1), а старший байт из адреса P(1)+1.

Функция 5

Прочесть целое число (2 байта) из сегмента с автоинкрементом адреса

ВходP(0)Сегмент
P(1)Адрес
ВыходP(2)Полученное целое число
P(1) = P(1) + 2

Младший байт берётся из адреса P(1), а старший байт из адреса P(1)+1.

Функция 6

Записать байт в сегмент

ВходP(0)Сегмент
P(1)Адрес
P(2)Записываемый байт
Выход

Функция 7

Записать байт в сегмент с автоинкрементом адреса

ВходP(0)Сегмент
P(1)Адрес
P(2)Записываемый байт
ВыходP(1) = P(1) + 1

Функция 8

Записать целое число (2 байта) в сегмент

ВходP(0)Сегмент
P(1)Адрес
P(2)Записываемое целое число
Выход

Младший байт записывается в адрес P(1), а старший байт в адрес P(1)+1.

Функция 9

Записать целое число (2 байта) в сегмент с автоинкрементом адреса

ВходP(0)Сегмент
P(1)Адрес
P(2)Записываемое целое число
ВыходP(1) = P(1) + 2

Младший байт записывается в адрес P(1), а старший байт в адрес P(1)+1.

Функция 10

Блочная пересылка данных между сегментами

Вход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, иначе результат непредсказуем.

Функция 11

Заполнить область ОЗУ байтом

ВходP(0)Сегмент
P(1)Начальный адрес
P(2)Байт
P(3)Длина области
Выход

P(3)+P(4) должно быть меньше &H4000, иначе результат непредсказуем.

Функция 12

Заполнить область ОЗУ байтом с автоинкрементом адреса.

ВходP(0)Сегмент
P(1)Начальный адрес
P(2)Байт
P(3)Длина области
ВыходP(1) = P(1) + P(3)

P(3)+P(4) должно быть меньше &H4000, иначе результат непредсказуем.

10.4. Функции доступа к VRAM

Функция 13

Прочесть байт из VRAM

ВходP(0)Блок VRAM
P(1)Адрес
ВыходP(2)Полученный байт

Функция 14

Прочесть байт из VRAM с автоинкрементом адреса

ВходP(0)Блок VRAM
P(1)Адрес
ВыходP(2)Полученный байт
P(0):P(1) = P(0):P(1) + 1

Функция 15

Прочесть целое число (2 байта) из VRAM

ВходP(0)Блок VRAM
P(1)Адрес
ВыходP(2)Полученный байт

Младший байт берётся из адреса P(1), а старший байт из адреса P(1)+1.

Функция 16

Прочесть целое число (2 байта) из VRAM с автоинкрементом адреса

ВходP(0)Блок VRAM
P(1)Адрес
ВыходP(2)Полученное целое число
P(0):P(1) = P(0):P(1) + 2

Младший байт берётся из адреса P(1), а старший байт из адреса P(1)+1.

Функция 17

Записать байт в VRAM

ВходP(0)Блок VRAM
P(1)Адрес
P(2)Записываемый байт
Выход

Функция 18

Записать байт в VRAM с автоинкрементом адреса

ВходP(0)Блок VRAM
P(1)Адрес
P(2)Записываемый байт
ВыходP(0):P(1) = P(0):P(1) + 1

Функция 19

Записать целое число (2 байта) в VRAM

ВходP(0)Блок VRAM
P(1)Адрес
P(2)Записываемое целое число
Выход

Младший байт записывается в адрес P(1), а старший байт в адрес P(1)+1.

Функция 20

Записать целое число (2 байта) в VRAM с автоинкрементом адреса

ВходP(0)Блок VRAM
P(1)Адрес
P(2)Записываемое целое число
ВыходP(0):P(1) = P(0):P(1) + 2

Младший байт записывается в адрес P(1), а старший байт в адрес P(1)+1.

Функция 21

Блочная пересылка данных из VRAM в RAM

Вход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, иначе результат непредсказуем.

Функция 22

Пакетная пересылка данных из RAM в VRAM

Вход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

Функция 23

Пакетная пересылка данных в пределах VRAM

Вход 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.

Функция 24

Заполнить область VRAM байтом

ВходP(0)Блок VRAM
P(1)Начальный адрес
P(2)Записываемый байт
P(3)Длина области (максимум 16кБ)
Выход

Чтобы заполнить область, размером больше 16кБ, используйте метод, описанный в функции 23.

Функция 25

Заполнить область VRAM байтом с автоинкрементом адреса

ВходP(0)Блок VRAM
P(1)Начальный адрес
P(2)Записываемый байт
P(3)Длина области (максимум 16кБ)
Выход:P(0):P(1) = P(0):P(1) + P(3)

Чтобы заполнить область, размером больше 16кБ, используйте метод, описанный в функции 23.

10.5. Функции для работы с диском

Функция 26

Поиск файла (S4)

Вход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-DOS 2, путь; 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-DOS 2 эти ошибки имеют свой собственный код).

Чтобы получить длину файла, можно использовать формулу P(9)+65536*P(10). При выводе на экран этих длин, помните, что представление числовых переменных различается в MSX BASIC и MSX X-BASIC для больших чисел; лучше всего отображать размер файлов сразу в килобайтах: INT(P(9)/1024)+64*P(10).

Функция 27

Переименование файла (S4)

ВходF$(0)Имя файла
F$(1)Новое имя файла
Выход

F$(0) может также включать имя диска и, в случае с MSX-DOS 2, путь; F$(1) должен содержать только новое имя файла. Под MSX-DOS можно переименовывать несколько файлов за один раз, используя маски; под MSX-DOS 2 можно переименовать только один файл за раз.

Функция 28

Удаление файла

ВходF$(0)Имя файла
Выход

F$(0) может также включать имя диска и, в случае с MSX-DOS 2, путь. Под MSX-DOS 2 эта функция выдаст ошибку, если Вы попытаетесь удалить открытый файл. Под MSX-DOS можно удалить открытые файлы, но это не рекомендуется, потому что последующие попытки доступа у этим файлам могут привести к непредсказуемым результатам.

Под MSX-DOS можно удалять несколько файлов за один раз, используя маски; под MSX-DOS 2 можно удалить только один файл за раз.

Функция 29

MSX-DOS 2

Перемещение файла (MSX-DOS 2)

ВходF$(0)Имя файла
F$(1)Новое расположение файла
Выход

Эта функция доступна только под MSX-DOS 2. Под MSX-DOS всегда возвращает ошибку 1.

F$(0) может также включать имя диска и путь. F$(1) не должен содержать ни имени файла (файл при перемещении сохраняет то же имя), ни буквы диска (файл может быть перемещен только в другой каталог на том же диске). Если задать каталог вместо файла в F$(0), все его подкаталоги и содержащиеся в нём файлы тоже будут перемещены.

Функция 30

Создание файла или директории

ВходF$(0)Имя файла или директории
P(0)Атрибуты при создании (игнорируются под MSX-DOS):
  • R + 2*H + 4*S для файлов
  • 2*H + 16 для директорий
  • R = 1 — только для чтения
  • H = 1 — скрытый
  • S = 1 — системный

F$(0) может также включать имя диска и путь. Файл будет создан с нулевой длиной и не останется открытым: для доступа к файлу, его нужно будет предварительно явно открыть (функция 31).

Под MSX-DOS можно создавать только файлы, и P(0) игнорируется. Под MSX-DOS 2 файлы всегда создаются с установленным атрибутом «архивный», в дополнение к атрибутам, заданным в P(0).

Функция 31

Открытие файла

ВходF$(0)Имя файла
ВыходP(0)Номер, назначенный файлу

F$(0) может содержать букву диска и, в случае с DOS 2, путь. Число, возвращаемое в P(0), идентифицирует файл, и будет указываться при последующих вызовах дисковых функций. Конкретное значение этого числа зависит от версии MSX-DOS и того, сколько файлов было открыто и закрыто ранее; не нужно воспринимать это значение как показатель текущего количества открытых файлов (используйте для этого функцию 1).

Под MSX-DOS, если превысить допустимое число одновременно открытых файлов, возникнет ошибка 3. Максимальное число одновременно открытых файлов под MSX-DOS можно узнать посредством 1-й функции.

Функция 32

Закрытие файла

ВходP(0)Номер файла
Выход

Очень важно закрывать файлы, которые уже не будут использоваться: иначе, если в них осуществлялась какая–то запись, во внутренних буферах MSX-DOS могут оставаться несохраненные данные, которые будут потеряны; к тому же, в этом случае, элемент каталога для этого файла не будет обновлён.

Функция 33

Чтение из файла (S4)

Вход 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.

Чтобы прочитать файл до конца, или прочитать весь файл, если он короче 16кБ, проще всего попытаться прочесть 16кБ (установить P(4)=&H4000) и игнорировать ошибку с кодом 1 или 199: для данной функции, эти ошибки означают лишь то, что был достигнут конец файла.

Если конец файла был достигнут до прочтения P(4) байт, будет выдана ошибка. Чтобы узнать число прочитанных байт, смотрите в P(7). Если нет ошибки, то в P(7) будет то же значение, что и в P(4); в случае физической ошибки (неисправная FAT, физическая ошибка диска или диск не вставлен), в P(7) всегда будет 0.

Функция 34

Чтение из файла в VRAM (S4)

Вход 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кБ), можно использовать приём, описанный в функции 23.

Для этой функции также действительны замечания насчет файлового указателя и значения P(7), сделанные в описании функции 33.

Функция 35

Чтение секторов диска (S4)

Вход 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).

Функция 36

Чтение секторов диска в VRAM (S4)

Вход 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кБ), можно использовать прием, описанный в функции 23.

Для этой функции также действительны соображения относительно значения P(7), сделанные в описании функции 35.

Функция 37

Запись в файл (S4)

Вход 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.

Функция 38

Запись в файл из VRAM (S4)

Вход 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кБ), можно использовать прием, описанный в функции 23.

Для этой функции также справедливы замечания касательно файлового указателя, сделанные в описании функции 37.

Функция 39

Запись в сектора диска (S4)

Вход 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).

Функция 40

Запись в сектора диска из VRAM (S4)

Вход 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кБ), можно использовать прием, описанный в функции 23.

Для этой функции также справедливы замечания, касающиеся значения P(7), представленные в описании функции 39.

Функция 41

Заполнение файла байтом (S4)

ВходP(0)Номер файла
P(1)Байт
P(4)Сколько байт записать (максимум &H4000)
ВыходP(7)Число фактически записанных байт

Эта функция просто записывает P(4) байт, равных содержимому P(1), в сегмент 4, начиная с адреса 0, и затем вызывает функцию 37 с P(2)=4 и P(3)=0. Поэтому, все замечания, сделанные в функции 37, будут также справедливы и здесь.

Функция 42

Перемещение файлового указателя

Вход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 байт), а запись в файл приведёт к тому, что пространство между концом файла и указателем будет заполнено нулями.

Функция 43

Узнать текущий диск и вектор доступных дисков (login vector)

Вход
ВыходP(0)Текущий диск (0=A:,…,7=H:)
P(1)Вектор доступных дисков

Вектор доступных дисков это байт, который содержит, в каждом бите, информацию о наличии или отсутствии (бит=1: присутствует, bit=0: отсутствует); младший бит соответствует диску A: а старший - диску H:. Например, если функция возвращает P(1)=&B01000011, значит присутствуют диски A:, B: и G:

Функция 44

Задать текущий диск

ВходP(0)Номер диска (0=A:,…,7=H:)
Выход

Эта функция выдаст ошибку 62 если попытаться установить текущим неверный диск (отсутствующий, или выше, чем 7).

Функция 45

Информация о дисковом пространстве

Вход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).

Функция 46

MSX-DOS 2

Узнать текущую директорию

ВходP(0)Привод (0=Текущий рабочий диск, 1=A:,…,8=H:)
ВыходF$(0)Текущая рабочая директория

Эта функция доступна только под MSX-DOS 2. Под MSX-DOS она будет всегда возвращать код ошибки 1.

Полученная строка не содержит имени привода, а также «\» ни в начале, ни в конце; так, корневая директория будет представлена в виде пустой строки.

Функция 47

MSX-DOS 2

Задать текущую директорию

ВходF$(0)Привод (опционально) + директория
Выход

Эта функция доступна только под MSX-DOS 2. Под MSX-DOS она будет всегда возвращать код ошибки 1.

Эта функция не меняет текущий рабочий диск. Чтобы сделать это, используйте функцию 44.

Функция 48

MSX-DOS 2

Узнать размер RAM-диска

Вход
ВыходP(0)размер RAM–диска в 16Кб сегментах

Эта функция доступна только под MSX-DOS 2. Под MSX-DOS она будет всегда возвращать код ошибки 1.

Чтобы получить размер RAM–диска в килобайтах, просто вычислите P(0)*16. Нулевой размер диска будет означать, что RAM–диск отсутствует.

Функция 49

MSX-DOS 2

Создать RAM–диск

ВходP(0)Размер (запрашиваемый) RAM-диска в 16Кб сегментах
ВыходP(0)Размер созданного RAM-диска в 16Кб сегментах

Эта функция доступна только под MSX-DOS 2. Под MSX-DOS она будет всегда возвращать код ошибки 1.

Так как по-умолчанию NestorBASIC при первоначальном запуске выделяет себе все свободные сегменты, нужно вызвать функцию 80 для начала, чтобы уменьшить количество сегментов, выделенных NestorBASIC; в противном случае, не будет свободных сегментов для RAM–диска (если только в компьютере не больше 4Мб ОЗУ).

Если нет P(0) свободных сегментов, но можно создать меньший по размеру RAM–диск, функция сделает это и не выдаст никакой ошибки; в P(0) будет возвращён размер созданного RAM–диска. Но если свободных сегментов не было вообще, и RAM–диск не был создан, тогда функция выдаст соответствующую ошибку.

Функция 50

MSX-DOS 2

Получить атрибуты файла

Вход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-DOS 2. Под MSX-DOS она будет всегда возвращать код ошибки 1.

Если P(0)=255, будет прочитан байт атрибутов для файла с именем, указанным в F$(0). F$(0) может содержать букву имени привода и путь;

Если нет, то будет прочитан байт атрибутов для уже открытого файла под номером P(0).

Функция 51

MSX-DOS 2

Установить атрибуты файла

Вход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-DOS 2. Под MSX-DOS она будет всегда возвращать код ошибки 1.

Если P(0)=255, то будет установлен байт атрибутов для файла с именем, заданным в F$(0). F$(0) может содержать букву имени привода и путь;

Иначе, байт атрибутов будет установлен для уже открытого файла под номером P(0).

Невозможно задать атрибуты уже открытого файла путём указания его имени в F$(0); если попытаться сделать это, произойдёт ошибка. Для открытого файла необходимо указывать его номер файла в P(0).

Для файлов — могут быть модифицированы только атрибуты системный, скрытый, только чтение и архивный;

Для директорий — только скрытый. Если вы попытаетесь изменить любой другой атрибут, вы получите ошибку. Нельзя изменить атрибуты «.» и «..» элементов каталога.

Функция 52

MSX-DOS 2

Синтаксический разбор пути

Вход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-DOS 2. Под 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.

10.6. Функции сжатия и распаковки графики

Функция 53

Сжатие графических данных

Вход 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.

Функция 54

Распаковка графических данных

Вход 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.

10.7. Другие различные функции

Функция 58

Выполнение подпрограммы в машинном коде, находящейся в BIOS, SUB-BIOS, основном ОЗУ MSX BASIC или системной рабочей области

Вход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(12)A
P(13)Cy flag (-1 если установлен, 0 если нет)
P(14)Z flag (-1 если установлен, 0 если нет)

С помощью этой функции можно вызвать машинную подпрограмму, расположенную в BIOS, 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, то будет запущена подпрограмма из SUB-BIOS, адрес которой указан в P(1); в этом случае, если указанный адрес больше, чем &H3FFF, будет возвращена ошибка с кодом -1. Для вызова подпрограмм 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

Функция 59

Выполнение подпрограммы пользователя (подпрограммы на машинном коде , размещённой в сегменте ОЗУ)

Вход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, и получения информации о прерываниях, среди прочего) могут использоваться пользовательскими подпрограммами в кодах. В приложении 2 вы можете найти список и подробное описание этих процедур и переменных.

Смотрите также описание функции 58 по поводу замечаний относительно возвращаемых значений P(12)–P(14).

Эта функция не поддерживает сегменты VRAM и 255 сегмент, и выдаст ошибку -1, если несуществующий сегмент указан в P(0).

Функция 60

Вывести строку на дисплей в графическом режиме

ВходF$(0)Строка
Выход

Эта функция работает только в видеорежимах со SCREEN 5 по 11, и эквивалентна команде

PRINT#1,F$(0)

,

предварённой командой

OPEN"GRP:"AS#1

Разница в том, что данная функция совместима с MSX X-BASIC. При вызове в других видеорежимах, эта функция не будет делать ничего, но не выдаст никакой ошибки.

Максимальная длина строки — 80 символов; если F$(0) больше, только первые 80 символов будут выведены. Строка не может содержать символа 0, потому что этот код интерпретируется как конец строки.

Функция 61

Сохранить строку в сегмент

Вход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) будет указан несуществующий сегмент.

Функция 62

Прочитать строку из сегмента

Вход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) будет указан несуществующий сегмент.

Функция 63

Инициализация режима мигания в SCREEN 0

Вход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

Функция 64

Создать или удалить мигающий блок символов

Вход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, эта часть не будет отображена.

Функция 65

Получить информацию о прерываниях

Вход
ВыходP(0)-1 если активен какой-либо процесс, работающий от прерываний (прерывание, определяемое пользователем, звуковой эффект PSG или воспроизведение музыки)
P(1)-1 если активно прерывание, определяемое пользователем
P(2)Сегмент прерывания, определяемого пользователем
P(3)Адрес прерывания, определяемого пользователем
P(4)-1 если проигрывается звуковой эффект PSG
P(5)-1 если воспроизводится музыка

P(2) и P(3) вернут сегмент и адрес прерывания, определяемого пользователем, даже если оно приостановлено. Если пользовательского прерывания не было определено, оба параметра будут нулевыми.

Чтобы получить больше информации о воспроизводимом звуковом эффекте, используйте функцию 67. Для музыки, используйте функцию 72.

Функция 66

Задать или приостановить прерывание, определяемое пользователем

Вход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.

10.8. Звуковые эффекты PSG

Функция 67

Получить информацию о звуковых эффектах PSG

ВходP(0)Новая максимальная громкость (от 0 до 15, -1 чтобы оставить без изменений)
ВыходP(1)-1 если проигрывается звуковой эффект
P(2)Номер воспроизводимого звукового эффекта (далее SFX), или последнего воспроизведенного
P(3)Приоритет воспроизводимого SFX, или последнего воспроизведенного
P(4)Сегмент набора эффектов
P(5)Адрес начала набора SFX
P(6)Наивысший определенный номер эффекта
P(7)Максимальная громкость

Результаты, возвращаемые данной функцией, будут действительны только если набор SFX был инициализирован функцией 68. Набор эффектов создается с помощью редактора SEE v3.xx, разработанного Fuzzy Logic.

Эта функция не возвращает никаких ошибок. Если значение, указанное в P(0), больше, чем 15, оно будет истрактовано как 15.

Функция 68

Инициализация набора звуковых эффектов PSG

ВходP(0)Сегмент
P(1)Адрес
Выход

Эта функция инициализирует набор звуковых эффектов, хранящийся в указанных сегменте и адресе, оставляя его готовым к использованию функцией 69.

Набор SFX создается с помощью редактора SEE v3.xx от Fuzzy Logic; если формат набора некорректен, функция выдаст ошибку 8.

Не допускается использование набора SFX, находящегося в сегменте VRAM или 255–м сегменте. Если в P(0) был указан несуществующий сегмент, произойдет ошибка -1.

Функция 69

Воспроизвести звуковой эффект PSG

ВходP(0)Номер эффекта
P(1)Приоритет (0: низкий, <>0: высокий)
Выход

Эта функция запускает проигрывание указанного SFX эффекта; набор эффектов создается с помощью редактора SEE v3.xx, созданного Fuzzy Logic. Если набор SFX не был инициализирован функцей 68, то поведение непредсказуемо.

P(1) управляет приоритетом в случае попытки воспроизвести эффект, когда уже воспроизводится другой. Это работает следующим образом:

  • Если новый и уже воспроизводимый SFX имеют одинаковый приоритет, то воспроизводимый SFX останавливается, и проигрывается новый.
  • Если воспроизводимый SFX имеет низкий приоритет, а новый - высокий, то происходит то же самое.
  • Если воспроизводимый SFX имеет высокий приоритет, а новый SFX - низкий, то старый SFX продолжает звучать, и функция возвращает ошибку 11.

Если звуковой эффект, указанный в P(0), не определен (первый трэк установлен в «OFF» в редакторе), функция вернет код ошибки 9. Если эффект не существует (его номер больше, чем последний определенный номер эффекта), функция вернет код ошибки 10.

Функция 70

Остановить воспроизведение звукового эффекта PSG

Вход
Выход

Эта функция останавливает воспроизведение звукового эффекта PSG, если таковой проигрывался, и заглушает PSG. Функция не выдает ошибок.

10.9. Функции для воспроизведения музыки в формате MoonBlaster

Функция 71

Загрузка и инициализация, или выгрузка Moonblaster-плеера (S4)

Вход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, оставляя готовым к использованию. Также, производит поиск всех присутствующих в системе звуковых чипов, и оставляет все найденные чипы включенными (см. функцию 73, чтобы узнать больше подробностей об активации звуковых чипов).

Проигрыватель может быть загружен только если сегмент 5 существует и принадлежит первичному мапперу; в противном случае, функция выдаст ошибку -1. Если случается дисковая ошибка, функция возвращает соответствующий код ошибки (см. раздел 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–плееры столько раз, сколько понадобится, в ходе выполнения программы. Если какой-то проигрыватель загружен, его легко можно заменить на другой, что очень удобно.

Функция 72

Получить информацию о проигрываемой музыке

Вход
Выход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)); функция не возвращает никаких ошибок. Для загрузки плеера используйте функцию 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) возвращается информация о обнаруженных звуковых устройствах, даже когда проигрыватель не загружен. Чтобы узнать информацию об активных звуковых устройствах, используйте функцию 73.

Функция 73

Активация и деактивация звуковых устройств

Вход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, все найденные звуковые устройства будут включены (это действие по-умолчанию при загрузке плеера). Для получения сведений о присутствии звуковых устройств используйте функцию 72.

Если P(0)=1, звуковые устройства будут активированы либо отключены согласно значениям, переданным в P(1)–P(3); попытки активировать устройства, которые отсутствуют в системе, будут проигнорированы. Если отключен и MSX Audio, и MSX Music (Moonblaster 1.4 player), или отключен OPL4 (Moonblaster Wave player), функция 74 (начало воспроизведения музыки) не будет ничего делать, но не выдаст никакой ошибки.

Изменения, сделанные этой функцией, не вступят в силу, пока играющая музыка не будет остановлена (функция 75 или 77), и запущена по новой (функция 74). Если никакой музыки не воспроизводилось в момент, когда Вы использовали данную функцию, просто стартуйте воспроизведение, обычным образом.

Эта функция вернет код ошибки 7, если какой-либо из входящих параметров не корректен (но если P(0)<>1, не требуется устанавливать P(1)–P(3)), и код ошибки 12, если плеер не загружен.

Функция 74

Старт воспроизведения Moonblaster–музыки

ВходP(0)Сегмент, в котором хранится музыка
P(1)Начальный адрес музыки
Выход

Эта функция запускает воспроизведение указанной Moonblaster–музыки. Если заданный сегмент не существует, является сегментом VRAM или 255–м, произойдет ошибка -1. Если не был загружен плеер, соответствующий типу музыки, возникнет ошибка 12 (используйте для загрузки проигрывателя функцию 71). Композиции Moonblaster Wave могут находиться в нескольких смежных сегментах; подробности см. в разделе 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) функцией 73, данная функция не произведёт никаких действий, и не выдаст никакой ошибки. Если в данный момент уже воспроизводится, или стоит на паузе, другая музыка — случится ошибка 14.

Функция 75

Останов воспроизведения музыки

Вход
Выход

Эта функция останавливает воспроизведение музыки и заглушает звуковые устройства. Если никакая музыка не играет в этот момент, или ни один музыкальный проигрыватель не загружен, функция не выполнит никаких действий. Она не возвращает ошибок.

Функция 76

Постановка на паузу и продолжение воспроизведения музыки

ВходP(0)0 → Поставить музыку на паузу
1 → Продолжить воспроизведение
-1 → Инвертировать текущее состояние (играть ←→ пауза)
Выход

Эта функция приостанавливает или возобновляет воспроизведение Moonblaster–музыки. Если никакая музыка не воспроизводится и не стоит на паузе, или проигрыватель не загружен, функция не будет ничего делать и не выдаст никакой ошибки. Если входной параметр недействителен, будет возвращена ошибка с кодом 7.

Функция 77

Постепенное затухание музыки

ВходP(0)0 → Только запросить информацию
-1 → Приостановить затухание
1..254 → Начать/продолжить затухание с заданным интервалом
ВыходP(1)1 если музыка в процессе затухания
P(2)Интервал задержки происходящего затухания
(-1 если затухание приостановлено)

Эта функция стартует затухание проигрываемой музыки. Интервал задержки это число тактов (1/50 или 1/60 секунды каждый) между шагами затухания, так, что наименьшая задержка соответствует наиболее быстрому затуханию. Как только затухание завершилось (громкость музыки уменьшилась до нуля), воспроизведение будет автоматически остановлено: Вам не придется останавливать его директивно функцией 75.

Если P(0)=-1, угасание будет приостановлено, то есть, музыка продолжит играть обычным образом, с достигнутым уровнем громкости. Чтобы возобновить затухание, просто вызовите эту функцию снова, указав новое значение задержки в P(0).

Если P(0)=0, данная функция только вернет в P(1) и P(2) актуальные значения. Если никакая музыка не играет, или проигрыватель не загружен, функция не сделает ничего. Она не возвращает ошибок.

Функция 78

Загрузка samplekit-а для Phillips NMS 1205 Music Module (S4)

Вход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.

Функция 79

Загрузить wavekit для Moonsound(S4)

Вход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 файл).

10.10. Функции назначения количества сегментов ОЗУ для использования NestorBasic

Функция 80

Узнать или задать количество сегментов выделенных для NestorBASIC

ВходP(0)Число сегментов, выделяемых NestorBASIC
(0: Не изменять, только получить число выделенных на данный момент сегментов)
Это число включает также сегменты NestorBASIC, MSX X-BASIC, и основного ОЗУ MSX BASIC
ВыходP(0)Число сегментов, выделенных NestorBASIC в результате исполнения функции
P(1)Максимальное число сегментов, которые могут быть выделены для NestorBASIC

Эта функция работает и в MSX-DOS, и в MSX-DOS 2, как бы то ни было, она предназначена для применения в MSX-DOS 2.

Под MSX-DOS 2, NestorBASIC, инициализируясь после загрузки, резервирует для себя все свободные сегменты в системе, вплоть до 247-го. Это означает, что не останется свободных сегментов для других резидентных программ, которые тоже осуществляют аллокацию памяти — такие как MSX-DOS 2 RAM-диск, NestorMan или 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-DOS 2, напротив, происходит реальное выделение и освобождение сегментов с использованием процедур MSX-DOS 2 для работы с маппером; в этом случае, значение, возвращаемое в P(1), пересчитывается при каждом вызове функции, и зависит от того, сколько сегментов было зарезервировано другими резидентными программами.

Функции для взаимодействия с NestorMan и InterNestor Suite/Lite

Функция 81

Проверка присутствия NestorMan и InterNestor Suite в ОЗУ

Вход
ВыходP(0)0 если NestorMan не присутствует
1 если NestorMan присутствует
3 если и NestorMan, и InterNestor Suite присутствуют
P(1)NestorMan-сегмент модуля InterNestor Suite level 1
P(2)NestorMan-сегмент модуля InterNestor Suite level 2
P(3)NestorMan-сегмент модуля InterNestor Suite level 3
P(4)NestorMan-сегмент модуля InterNestor Suite level 4
P(5)Номер сегмента NestorMan сегмента 4 NestorBASIC

Значение, возвращаемое в P(5) будет действительно, только если P(0) равно 1 или 3 на выходе. Это значение требуется для того, чтобы осуществлять обмен данными между сегментом NestorMan и сегментом NestorBASIC, используя сегмент 4 (общий для обей программ) как промежуточный буфер, как описано в разделе 9.2.

Значения, возвращаемые в P(1)–P(4), будут действительны только если P(0) равно 3 на выходе. Не обязательно знать расположение модулей InterNestor Suite, чтобы вызывать его подпрограммы (используя функцию 85), но это необходимо знать, чтобы читать и записывать конфигурационные константы и переменные модулей, как описано в разделе 9.3.

Функция 82

Выполнить функцию 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)

Эта функция вызывает функцию NestorMan, указанную в P(0), посредством метода непрямого вызова, то есть, используя hook расширенного BIOS. Таким образом, это равносильно использованию функции 58 с установленными предварительно P(1)=&HFFCA, P(3)=Функция+256*B, и P(4)=&H2202.

Функцией будет возвращен код ошибки -1, если NestorMan отсутствует. Отметьте, тем не менее, что не производится проверка, существует ли действительно в NestorMan указанная функция.

См. также описание функции 58 для понимания выходных значений P(12)–P(14).

Раздел 9 демонстрирует некоторые техники для обмена данными между NestorMan и NestorBASIC.

Функция 83

Передача блока данных из сегмента NestorMan в сегмент NestorBASIC

ВходP(0)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) соотносится с сегментом NestorMan. Как и в случае с функцией 10, P(3)+P(4) должно быть меньше &H4000, в P(2) может быть указан сегмент VRAM или 255–й сегмент, и ошибка -1 будет выдана, если любой из указанных сегментов не существует.

У данной функции есть одно ограничение: её нельзя использовать, указав сегмент 1 в качестве NestorBASIC–сегмента назначения. Как правило, это не является проблемой, потому что 1–й сегмент содержит компилятор MSX X-BASIC, и обычно никому не нужно менять его содержимое. Если, тем не менее, передача в 1-й сегмент необходима, Вам придется сначала скопировать данные в какой-то другой сегмент, в качестве промежуточного шага — например, в сегмент 4.

Функция 84

Передача блока данных из сегмента NestorBASIC в сегмент NestorMan

ВходP(0)NestorBASIC-сегмент источника
P(1)Начальный адрес источника
P(2)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) соотносится с сегментом NestorMan. Как и в случае с функцией 10, P(3)+P(4) должно быть меньше &H4000, в P(0) может быть указан сегмент VRAM или 255–й сегмент, и ошибка -1 будет выдана, если любой из указанных сегментов не существует.

У данной функции есть одно ограничение: её нельзя использовать, указав сегмент 1 в качестве NestorBASIC–сегмента источника. Как правило, это не является проблемой, потому что 1–й сегмент содержит компилятор MSX X-BASIC, и обычно никому не нужно менять его содержимое. Если, тем не менее, передача в 1–й сегмент необходима, Вам придется сначала скопировать данные в какой-то другой сегмент, в качестве промежуточного шага - например, в сегмент 4.

Функция 85

Вызов процедуры InterNestor Suite

Вход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)

С помощью этой функции можно вызвать любую подпрограмму любого из модулей InterNestor Suite. Чтобы читать или изменять конфигурационные константы и переменные модулей, нужно сначала узнать номера NestorMan-сегментов модулей, используя функцию 81, а затем применить любой из приемов, описанных в разделе 9.2, для обмена данными между NestorBASIC и NestorMan.

Данная функция выдаст ошибку -1, если InterNestor Suite отсутствует в памяти, или в P(0) указан недействительный номер модуля.

См. также описание функции 58 для понимания выходных значений P(12)–P(14).

Раздел 9.3 содержит некоторые соображения насчет совместного использования NestorBASIC и InterNestor Suite.

Функция 86

Вызов процедуры InterNestor Lite

Вход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)

С помощью этой функции можно вызвать любую процедуру InterNestor Lite. P(1) должен содержать адрес какой-либо из подпрограмм InterNestor Lite, перечисленных в его руководстве программиста, иначе результаты исполнения данной функции непредсказуемы.

Данная функция выдаст ошибку -1, если InterNestor Lite отсутствует в памяти. Чтобы заранее узнать, загружен InterNestor Lite или нет, используйте следующий код, в котором применяется метод обнаружения, описанный в разделе 9.4:

P(0)=0: P(1)=&HFFCA: P(2)=0: P(4)=&H2203: E=USR(58):
IF P(12)=0 THEN ... (отсутствует)

В разделе 9.4 есть комментарий относительно применения процедур InterNestor Lite для обмена данными с TPA из NestorBASIC. См. также описание функции 58 для понимания выходных значений P(12)–P(14).

Следующий пример выводит номер версии 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 и InterNestor Lite.

Приложение 1

Функции, которые используют 4-й сегмент, имеют метку «(S4)» после их названий.
Это функции: 0, 26-28, 30, 33-41, 55-57, 71, 78, и 79.

Общие функции
Функция 0Выгрузка NestorBASIC'а из памяти (S4)
Функция 1Получение общей информации о NestorBASIC и конкретном логическом сегменте
Функции для доступа к логическим сегментам
Функция 2Прочесть байт из сегмента
Функция 3Прочесть байт из сегмента с автоинкрементом адреса
Функция 4Прочесть целое число (2 байта) из сегмента
Функция 5Прочесть целое число (2 байта) из сегмента с автоинкрементом адреса
Функция 6Записать байт в сегмент
Функция 7Записать байт в сегмент с автоинкрементом адреса
Функция 8Записать целое число (2 байта) в сегмент
Функция 9Записать целое число (2 байта) в сегмент с автоинкрементом адреса
Функция 10Блочная пересылка данных между сегментами
Функция 11Заполнить область ОЗУ байтом
Функция 12Заполнить область ОЗУ байтом с автоинкрементом адреса
Функции доступа к VRAM
Функция 13Прочесть байт из VRAM
Функция 14Прочесть байт из VRAM с автоинкрементом адреса
Функция 15Прочесть целое число (2 байта) из VRAM
Функция 16Прочесть целое число (2 байта) из VRAM с автоинкрементом адреса
Функция 17Записать байт в VRAM
Функция 18Записать байт в VRAM с автоинкрементом адреса
Функция 19Записать целое число (2 байта) в VRAM
Функция 20Записать целое число (2 байта) в VRAM с автоинкрементом адреса
Функция 21Блочная пересылка данных из VRAM в RAM
Функция 22Пакетная пересылка данных из RAM в VRAM
Функция 23Пакетная пересылка данных в пределах VRAM
Функция 24Заполнить область VRAM байтом
Функция 25Заполнить область VRAM байтом с автоинкрементом адреса
Функции для работы с диском
Функция 26Поиск файла (S4)
Функция 27Переименование файла (S4)
Функция 28Удаление файла
Функция 29Перемещение файла (MSX-DOS 2)
Функция 30Создание файла или директории
Функция 31Открытие файла
Функция 32Закрытие файла
Функция 33Чтение из файла (S4)
Функция 34Чтение из файла в VRAM (S4)
Функция 35Чтение секторов диска (S4)
Функция 36Чтение секторов диска в VRAM (S4)
Функция 37Запись в файл (S4)
Функция 38Запись в файл из VRAM (S4)
Функция 39Запись в сектора диска (S4)
Функция 40Запись в сектора диска из VRAM (S4)
Функция 41Заполнение файла байтом (S4)
Функция 42Перемещение файлового указателя
Функция 43Узнать текущий диск и вектор доступных дисков (login vector)
Функция 44Задать текущий диск
Функция 45Информация о дисковом пространстве
Функция 46Узнать текущую директорию (MSX-DOS 2)
Функция 47Задать текущую директорию (MSX-DOS 2)
Функция 48Узнать размер RAM-диска (MSX-DOS 2)
Функция 49Создать RAM–диск (MSX-DOS 2)
Функция 50Получить атрибуты файла (MSX-DOS 2)
Функция 51Установить атрибуты файла (MSX-DOS 2)
Функция 52Синтаксический разбор пути (MSX-DOS 2)
Функции сжатия и распаковки графики
Функция 53Сжатие графических данных
Функция 54Распаковка графических данных
Функции для запуска программ на BASIC
Функция 55Запуск программы на BASIC, находящейся в сегменте (S4)
Функция 56Актуализация программы на BASIC, находящейся в сегменте (S4)
Функция 57Сохранить программу на BASIC со специальным заголовком (S4)
Другие различные функции
Функция 58Выполнение подпрограммы в машинном коде
Функция 59Выполнение подпрограммы пользователя
Функция 60Вывести строку на дисплей в графическом режиме
Функция 61Сохранить строку в сегмент
Функция 62Прочитать строку из сегмента
Функция 63Инициализация режима мигания в SCREEN 0
Функция 64Создать или удалить мигающий блок символов
Функция 65Получить информацию о прерываниях
Функция 66Задать или приостановить прерывание, определяемое пользователем
Звуковые эффекты PSG
Функция 67Получить информацию о звуковых эффектах PSG
Функция 68Инициализация набора звуковых эффектов PSG
Функция 69Воспроизвести звуковой эффект PSG
Функция 70Остановить воспроизведение звукового эффекта PSG
Функции для воспроизведения музыки в формате MoonBlaster
Функция 71Загрузка и инициализация, или выгрузка Moonblaster-плеера (S4)
Функция 72Получить информацию о проигрываемой музыке
Функция 73Активация и деактивация звуковых устройств
Функция 74Старт воспроизведения Moonblaster–музыки
Функция 75Останов воспроизведения музыки
Функция 76Постановка на паузу и продолжение воспроизведения музыки
Функция 77Постепенное затухание музыки
Функция 78Загрузка samplekit-а для Phillips NMS 1205 Music Module (S4)
Функция 79Загрузить wavekit для Moonsound(S4)
Функции назначения количества сегментов ОЗУ для использования NestorBasic
Функция 80Узнать или задать количество сегментов выделенных для NestorBASIC
Функции для взаимодействия с NestorMan и InterNestor Suite/Lite
Функция 81Проверка присутствия NestorMan и InterNestor Suite в ОЗУ
Функция 82Выполнить функцию NestorMan
Функция 83Передача блока данных из сегмента NestorMan в сегмент NestorBASIC
Функция 84Передача блока данных из сегмента NestorBASIC в сегмент NestorMan
Функция 85Вызов процедуры InterNestor Suite
Функция 86Вызов процедуры InterNestor Lite

Приложение 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
Указатель на таблицу сегментов. Формат этой таблицы следующий:

-2Максимальное число сегментов, доступных для аллоцирования NestorBASIC (неизменное значение под MSX-DOS 1; под MSX-DOS 2 это значение действительно лишь сразу после загрузки NestorBASIC, и может меняться после)
-1Количество аллоцированных сегментов (аналогично P(0), возвращаемому функциями 1 и 80)
+0Слот логического сегмента 0
+1Физический сегмент логического сегмента 0
+2Слот логического сегмента 1
+3Физический сегмент логического сегмента 1
+492Слот логического сегмента 246
+493Физический сегмент логического сегмента 246

&H4112: INT_DATA
Содержит информацию об активных прерываниях NestorBASIC:

бит 0 = 1Пользовательское прерывание активно
бит 1 = 1Звуковой эффект активен
бит 2 = 1Музыка Moonblaster 1.4 воспроизводится
бит 3 = 1Музыка Moonblaster Wave воспроизводится

&H4113: PUTSLOT0
Подключает слот к странице 0 без использования ENASLT. После возврата из данной процедуры прерывания запрещены.

ВходA = Номер слота, который надо подключить
Выход
РегистрыAF

&H4116: CHKSLE
Проверяет, существует ли логический сегмент. НЕ распознает как действительные, сегменты, соответствующие VRAM, а также 255–й.

ВходA = Логический сегмент
ВыходCy= 1 — Логический сегмент существует
Cy= 0 — Логический сегмент не существует
РегистрыF

&H4119: CHKSLFF
Проверяет, является ли логический сегмент 255–м, и в этом случае преобразует его в соответствующий сегмент (текущий сегмент страницы 2 если HL<&HC000, сегмент 3 если HL>=&HC000)

Вход A = Логический сегмент
HL = Адрес
ВыходA = Преобразованный номер сегмента, если это был 255–й, иначе — не измененный
РегистрыF

&H411C: CHKSLV
Проверяет, является ли логический сегмент сегментом VRAM, и если да, то преобразует его в соответствующий адрес VRAM.

ВходA = Логический сегмент
HL = Адрес
ВыходЕсли является VRAM:
A = Блок VRAM
HL = Адрес VRAM
Cy = 1
Если не является VRAM:
A, HL неизменны
Cy = 0
Регистры

&H411F: VTOSL
Преобразует адрес VRAM в соответствующий ему логический сегмент.

ВходA = Блок VRAM
HL = Адрес VRAM
ВыходA = Соответствующий логический сегмент
HL = Соответствующий адрес ОЗУ
Cy = 1 — на входе A=1, но только 64K VRAM присутствует
РегистрыF

&H4122: GET_SF
Получить физический сегмент и слот, соответствующие логическому сегменту.

ВходA = Логический сегмент
ВыходA = Физический сегмент
B = Слот (255 — Логический сегмент не существует)
Регистры

&H4125: GET_SLT Узнать слот, подключенный в страницу 1 или 2.

ВходA = Страница (1 или 2)
ВыходB = Слот
РегистрыF, C

&H4128: READ_SL
Прочесть один байт из логического сегмента.

ВходA = Логический сегмент
HL = Адрес (0—&H3FFF)
ВыходA = Прочитанный байт
РегистрыF, AF'

&H412B: WRITE_SL
Записать байт в логический сегмент

ВходA = Логический сегмент
E = Записываемый байт
HL = Адрес (0—&H3FFF)
Выход
РегистрыF, AF'

&H412E: LDIRSS
Осуществляет копирование данных из одного логического сегмента в другой. Распознает логический сегмент 255 и сегменты VRAM. Возвращается с BIOS подключенным в страницу 0. Не проверяет случаи, когда BC>&H4000.

ВходIXh = Логический сегмент источника
IXl = Логический сегмент назначения
HL = Адрес источника (0..&HFFF)
DE = Адрес назначения (0..&HFFF)
BC = Длинна (0..&H3FFF)
ВыходA = 0 — Пересылка осуществлена
A <> 0 — Один из логических сегментов не существует
РегистрыВсе

&H4131: CHKBV
Проверяет, существует ли адрес VRAM.

ВходA = Блок VRAM (0 или 1, нижние или верхние 64K)
ВыходCy = 1 — Такого адреса не существует
(A = 1, но у компьютера только 64K VRAM)
Регистры

&H4134: SET_RD
Подготавливает VDP к чтению VRAM.

ВходHL = Адрес VRAM, младшие 16 бит
CY = Адрес VRAM, 17–й бит
Выход
РегистрыAF, HL

&H4137: SET_WR
Подготавливает VDP к записи в VRAM.

ВходHL = Адрес VRAM, младшие 16 бит
CY = Адрес VRAM, 17–й бит
Выход
РегистрыAF, HL

&H413A: LDIRVR
Копирует блок данных из VRAM в RAM.

ВходАдрес VRAM, заданный с помощью SET_RD
DE = Адрес назначения в RAM
BC = Длина
ВыходDE = Адрес конца блока +1
РегистрыAF

&H413D: LDIRRV
Копирует блок данных из RAM в VRAM.

ВходАдрес VRAM, заданный с помощью SET_WR
HL = Адрес источника в RAM
BC = Длина
ВыходHL = Адрес конца блока +1
РегистрыAF

&H4140: LDIRVV
Копирует блок данных из VRAM в VRAM через буфер в RAM.

ВходHL = Источник, младшие 16 бит
DE = Назначение, младшие 16 бит
BC = Длина
A = %000000 Н И, бит 17 Источника и Назначения
IX = Буфер в ОЗУ размером как минимум BC байт
Выход
РегистрыAF, HL, DE

&H4143: FILLVR
Заполняет область VRAM байтом.

ВходНачальный адрес установлен посредством SET_WR
BC = Длина
A = Записываемый байт
Выход
Регистры

&H4146: BLK_CLS
Очищает область VRAM предназначенную для режима мигания (SCREEN 0 «blink» mode).

Вход
Выход
РегистрыAF

&H4149: BLK_COL
Устанавливает цвета режима мигания.

ВходA = Цвет «мигнувшего» текста + 16* цвет «мигнувшего» фона
Выход
РегистрыA

&H414C: BLK_TIM
Устанавливает временные интервалы режима мигания.

ВходA = Время ВКЛ + 16* время ВЫКЛ
Выход
РегистрыA

&H414F: BLK_ON
Создание мигающего блока.

ВходHL = XXYY
B = Размер X
C = Размер Y
ВыходL = YY последней строки + 1
H не изменяется
РегистрыAF

&H4152: BLK_OF Удаление мигающего блока.

ВходHL = XXYY
B = Размер X
C = Размер Y
ВыходL = YY последней строки + 1
H = не изменяется
РегистрыAF

&H4155: C_BLKAD
Вычисление адреса VRAM, соответствующего заданным координатам мигающего блока.

ВходHL = XXYY
ВыходHL = Адрес VRAM
РегистрыAF

&H4158: C_STBT
Вычисление бита, соответствующего заданным координатам мигающего блока.

ВходA = Координата X
ВыходA = Бит, установленный в 1
РегистрыF

&H415B: GINFOUS
Выдает информацию о прерывании пользователя.

Вход
ВыходA = Сегмент
HL = Адрес

&H415E: GINFOSFX
Выдает информацию о звуковых эффектах PSG

ВходA = Новая максимальная громкость (-1 чтобы оставить без изменений)
ВыходA = Сегмент воспроизведения эффектов
HL = Адрес воспроизведения эффектов
B = Номер эффекта, который звучит, или последнего, который звучал
C = Приоритет эффекта, который звучит, или последнего, который звучал
D = Наибольший номер эффекта, который существует
E = Максимальная громкость

&H4161: GINFOMUS
Выдает информацию о музыке, которая проигрывается, и о присутствии плеера Moonblaster.

Вход
Выход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 (&H4161).

&H4165: GETF01

Вход
Выход

Эта процедура копирует содержимое строковых массивов F$(0) y F$(1) в два буфера NestorBASIC, находящихся в странице 3; адреса этих буферов указаны в переменных F0BUFADD и F1BUFADD, упоминаемых позже.

Копируется только первые 80 символов строк. В конце их добавляется символ 0.

&H4168: SETF0
&H416B: SETF1

Вход
Выход

Эти процедуры заносят в строковые массивы 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
Номер сегмента NestorMan, соответствующего сегменту 4 NestorBASIC.

&H4174: INS_SL1 &H4175: INS_SL2 &H4176: INS_SL3 &H4177: INS_SL4
Номера сегментов NestorMan модулей InterNestor Suite с 1 по 4, соответственно.

Приложение 3

Прерывания на MSX Turbo-R

NestorBASIC отлично работает на любом MSX 2/2+/Turbo-R, но может вызвать проблемы с прерываниями, если исполняется на Turbo-R в режиме MSX-DOS 1, особенно если используется внешнее расширение ОЗУ. Это связано с тем, что перед выполнением прерывания, NestorBASIC должен убедится, что сегмент подключен в страницу 1, и в режиме MSX-DOS 1 это может быть сделано только инструкцией IN A,(&HFD), которая на Turbo-R работает не совсем так, как на MSX2/2+.

Поэтому, если Вы собираетесь использовать пользовательские прерывания или звуковые эффекты в программе, которая использует NestorBASIC, самое лучшее будет проверять — является ли компьютер Turbo-R (если PEEK(&H2D)=3), и не работает ли в режиме MSX-DOS 1 (это можно сделать функцией 1), и в этом случае сообщить пользователю, что требуется загрузиться в режиме MSX-DOS 2.

Приложение 4

Условия использования

NestorBASIC это бесплатная программа, или, на профессиональном языке, freeware.

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

  • Где-нибудь в программе (при загрузке, в разделе «О программе», и т.п.) должно появляться упоминание об использовании NestorBASIC, а также его версия (чтобы узнать версию NestorBASIC, используйте функцию 1).
  • Если программа предназначена не исключительно для личного пользования автора (то есть, если она будет распространяться бесплатно или за плату), нужно предоставить мне ее копию.

Если у вас есть предложения, вопросы или комментарии относительно NestorBASIC, вы можете связаться со мной по адресу konamiman@konamiman.com.

Использование звуковых эффектов, созданных в редакторе 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.

Ссылки

msx/nestor_basic/nestor_basic.txt · Последние изменения: 2023-07-18 22:38 — ATroubleshooter