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

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


msx:nestor_basic:nestor_basic

NestorBASIC

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

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

  • Полный доступ ко всей страничной оперативной памяти компьютера(всей памяти, в случае MSX-DOS 1, всей свободной памяти в случае 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 для подробностей).

Файл NestorBASIC 1.11, оригинал

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

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

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

0xC000 + (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), доступных, когда они подключены в адресное пространство активного слота памяти, что контролируется через порты с 0xFC по 0xFF.

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

Адресное пространство логического сегмента (далее — просто «сегмента») от 0x0000 до 0x3FFF. Если заданы более высокие адреса при вызове функций NestorBASIC, они будут преобразованы. То есть, адреса 0x4000–0x7FFF, 0x8000–0xBFFF и 0xC000–0xFFFF эквивалентны 0x0000–0x3FFF при доступе к сегментам ОЗУ через NestorBASIC.

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

  1. Сегмент 0 содержит собственно NestorBASIC, и лишь небольшая область ОЗУ остаётся доступной для пользователя в конце него. Используйте функцию 1 чтобы получить начальный адрес этой области (описание функции см. в разделе 10).
  2. Сегмент 1 содержит компилятор MSX X-BASIC. Можно перезаписать этот сегмент только в том случае, если Вы не собираетесь использовать компилятор.
  3. Сегмент 2 всегда подключён к 2 странице (адреса 0x8000–0xBFFF), и содержит исполняемую программу на MSX BASIC и часть её переменных.
  4. Сегмент 3 всегда подключён к странице 3 (адреса 0xC000–0xFFFF), и содержит рабочую область системы и часть переменных программы на 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.

При использовании функций обмена блоками данных, нужно быть осторожным, чтобы сумма адреса назначения и длинны пересылаемого блока не превысила адрес 0x3FFF (например, не пытайтесь переслать 0x2000 байт указывая адрес 0x3000 как адрес назначения). В таком случае, сегмент 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 и 128K VRAM. Если программа работает в текстовом режиме, используются только первые 2000 байт VRAM: это видео–ОЗУ соответствует последнему сегменту VRAM, под номером 79. В этом случае, программист может свободно использовать сегменты с 72 по 78, и диапазон доступных сегментов будет 0–78, без необходимости пропускать какой–либо сегмент внутри этой последовательности. Если программа работает в SCREEN 5 и использует только графическую страницу 0, диапазон сегментов будет с 0 по 77; в SCREEN 7 он будет с 0 по 75, и т.д.

Конечно, NestorBASIC также имеет функции для работы с VRAM напрямую, без эмуляции в ней сегментов RAM. Эти функции позволяют пересылать данные VRAM←→RAM и VRAM←→файл.

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

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

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

3.3. Сегмент 255

Логический сегмент 255 имеет особое предназначение. Он соотносится не с каким–то конкретным сегментом RAM или VRAM, а с основной памятью MSX BASIC, то есть — c ОЗУ используемым MSX BASIC по адресам 0x8000–0xFFFF (к нему не применяются ни ограничения, ни преобразования адресов в диапазон 0x0000–0x3FFF, как к другим сегментам). Это удобно использовать для обмена данными между каким–либо сегментом и переменной MSX BASIC или массивом переменных:

 1 'Copy 10 bytes from segment 7, begin address 0x1000,
 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)=0x1000	     '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 (0x8000–0xBFFF)
3Основная память MSX BASIC, страница 3 (0xC000–0xFFFF)
4Сегмент служебного буфера
5 по S-1Память, доступная программе пользователя (если S>5)
Если загружен музыкальный плейер, он находится в сегменте 5. См. раздел 8.
VRAMVRAM 64 Кб
S0x1C000–0x1FFFF0xC000–0xFFFF
S+10x18000–0x1BFFF0x8000–0xBFFF
S+20x14000–0x17FFF0x4000–0x7FFF
S+30x10000–0x13FFF0x0000–0x3FFF
S+40x0C000–0x0FFFF
S+50x08000–0x0BFFF
S+60x04000–0x07FFF
S+70x00000–0x03FFF
S+8 до 254Отсутствуют (если S+8<255)
255Основная память MSX BASIC (0x8000–0xFFFF)

3.5. Ошибки

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

  • Указан номер отсутствующего сегмента памяти
  • Попытка доступа к адресу VRAM выше 0xFFFF в компьютерах с 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, функции работы с диском имеют собственные коды ошибок.

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

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

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

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

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

FIXME

Ссылки

msx/nestor_basic/nestor_basic.txt · Последние изменения: 2021-10-10 15:49 — ATroubleshooter