Содержание

VBC — MSX–совместимый компилятор BASIC

Автор: Егор Вознесенский

FIXME

Основные разделы:

Файлы:

vbc.dsk на основе vbc27b, оригинал
Открыть диск в WebMSX

Содержание

Часть I. Руководство пользователя

Глава 1. Что такое VBC ?

Компилятор создавался с целью получения языка, максимально приближенного к MSX BASIC. Более того, поскольку возможна отладка с помощью интерпретатора, из компилятора исключена диагностика некоторых ошибок, которые можно выявить в процессе отладки на интерпретаторе.

Входной язык представляет собой несколько расширенную версию MSX BASIC, состоящую из ядра и расширенную следующими функциями:

Глава 2. Как запускать компилятор

Если у вас есть уже готовая программа на BASIC, то чтобы её оттранслировать достаточно лишь набрать команду:

A>BAS <имя файла> [ввод]

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

Для более любознательных сообщаю, что компилятор можно запустить и без BAT-файла командой

A>VBC <имя файла>.<ext> [/C]

Имя файла нужно указать полное, с расширением.
Необязательный ключ /C указывает компилятору, что нужно произвести только проверку синтаксиса, без создания выходного файла.

При работе компилятор сообщит вам свою версию, может напечатать листинг программы (для этого следует включить в текст программы операторы PRAGMA LIST), а в конце работы — распечатает список всех объявленных переменных и количество обнаруженных ошибок. Если ошибок не было обнаружено, выводится сообщение

complete

Часть II. Руководство программиста

Глава 1. Совместимость со стандартами

1.1. ГОСТ–совместимость

Входной язык компилятора полностью включает в себя ЯДРО и расширен в соответствии с УРОВНЕМ1 и УРОВНЕМ2 расширения.
Кроме того, он поддерживает ряд опций, не предусмотренных в ГОСТ, а именно:

Кроме того, часть возможностей, специфицированных в расширенных модулях ГОСТ не реализована в связи с изменением модели распределения памяти времени компиляции (см. п.1.3).

1.2. Совместимость с MSX

FIXME

Компилятор соответствует MSX BASIC, с учётом пп. 1.1 и 1.3 и включает в себя:

Соответствие MSX-2 стандарту:

Соответствие MSX 2 + стандарту:

Примечание: *) — звёздочкой отмечены полностью совместимые с MSX-стандартом разделы, в которых имеется, однако, одно исключение: в макроязыке операторов DRAW и PLAY не определён параметр X (смотри руководство по MSX BASIC), что обусловлено особенностями работы откомпилированной программы с памятью.

Функции, соответствующие более позднему MSX-стандарту, могут быть реализованы на машине более раннего стандарта при условии наличия необходимых аппаратных средств и (или) BIOS. Например SET SCROLL можно выполнять на всех компьютерах с V9938, но при этом скроллинг будет только по вертикали.

Часть операторов (например SET PASSWORD или SET VIDEO), не реализованы или как не имеющие смысла в откомпилированной программе или как редко употребляемые. Их, при необходимости, можно эмулировать соответствующими комбинациями OUT'ов.

1.3. Отходы от стандартов

Отходы от стандартов обусловлены оптимизацией получаемого кода и невозможностью реализации части функций в модели компилируемой программы. Эти отходы перечислены ниже:

Для облегчения адаптации программ в конце данного руководства помещён список ошибок и возможные их причины.

Глава 2. Преимущества компилятора IBAS

Главным преимуществом откомпилированной программы является во много раз большая скорость её исполнения, что особенно заметно при целочисленных операциях. В данном случае мы имеем ускорение вычислений в 20…50 раз по сравнению с интерпретатором в зависимости от типа программы. (это для целых чисел). Скорость вычислений с плавающей точкой возрастает в 1.3…2.5 раза в основном за счет операций загрузки/записи. Скорость выполнения строковых операций зависит от типа операции, но в целом немного выше, чем в интерпретаторе. Особенно быстро выполняются короткие циклы в целых числах с вычислением массивов внутри них.

Компилятор снабжен мощным оптимизатором и ориентирован на написание программ управляющего характера, в связи с чем в нем основным типом данных являются целые числа. Такие популярные функции, как RND и SQR имеют версии для целых аргументов, возвращающие также целое число и чрезвычайно быстродействующие. Деление при применении к двум целым также возвращает целое т.е. a% / b% =a% \ b% .

Компилятор совместим с MSX ASCII C при вызове из MSX BASIC внешних подпрограмм. Кроме того он имеет средства раздельной компиляции модулей, написанных на MSX BASIC.

Что касается скорости компиляции, то она несколько превосходит скорость компиляции аналогичной программы компилятором MSX-C, а за счёт использования некоторых ухищрений при оптимизации и специфических команд процессора Z80 оптимальность получаемого кода не меньше, а местами даже больше, чем у семантически аналогичной программы, написанной на C и откомпилированной компилятором MSX ASCII C.

На выходе компилятора получается программа на ассемблере в мнемонике Z80, что также лучше, чем мнемоника 8080 на выходе MSX ASCII C. При желании квалифицированный программист может внести изменения уже в файл ассемблера. Для облегчения таких работ у компилятора имеется опция, позволяющая вводить исходный текст программы на MSX BASIC в выходной файл в виде комментариев.

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

В общем, данный компилятор является на данный момент практически единственным компилятором, собирающим в себе все возможности и на таком уровне совместимый со стандартом MSX.

Глава 3. Ядро компилятора

3.1. Переменные и массивы

Переменные и массивы идентифицируются по имени, причём оно может быть произвольной длины. В соответствии со стандартом на MSX BASIC, имена различаются по первым двум символам, первый из которых должен быть латинской буквой, а второй — буквой или цифрой. Не допускается использование русских букв и графических символов. Строчные латинские буквы переводятся в прописные.

Сразу после имени переменной может стоять необязательный символ типа:

%для целой переменной
$для символьной переменной
!для переменной одинарной точности
#для переменной двойной точности

Если таковой не стоит, то тип переменной определяется по первому символу имени переменной в соответствии с оператором DEF, имеющему вид:

DEF {INT|STR|SNG|DBL} <символ>[- <символ>]…

,

где

В отличие от MSX BASIC по умолчанию все переменные определены как целые, поэтому следует в программах первой строкой вставить DEFDBL A-Z. Напротив, конструкцию типа DEFINT A-Z можно опустить.

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

Кроме того, нельзя использовать массивы, объявленные по умолчанию.

Тип переменной устанавливается компилятором один раз при первой встрече согласно правилам, описанным выше, и остаётся неизменным на протяжении всей программы, поэтому символ точности можно указывать только один раз, что экономит текст программы и избавляет пользователя от возможных ошибок в результате пропуска такого символа в программе.

Все перечисленные отличия от стандарта MSX не являются прямыми противоречиями ГОСТ и введены для улучшения стиля программ, написанных на BASIC.

3.2. Выражения

3.2.1. Математические выражения

В выражениях можно применять следующие операции, причём в следующем приоритете (начиная с наинизшего) :

Операция «/» при применении к двум целым возвращает целый результат, т.е. работает аналогично «\».

Операции «\» и MOD преобразуют оба аргумента в целый тип. MOD возвращает остаток от деления.

  1. операция возведения в степень ^
  2. операция смены знака - (одноместная)
  3. операции в скобках и оператор присваивания (см. 3.2.2)
  4. функции (см. 3.2.3)

3.2.2. Оператор присваивания

Оператор присваивания имеет вид:

[ LET ] { переменная | массив } = <выражение>

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

Во всех остальных случаях результатом будет адрес переменной или массива, куда произошло присваивание.

3.2.3 Функции

В математических выражениях можно употреблять функции, определённые в MSX, причём их действие стандартно, поэтому здесь будут полно описаны лишь три функции, которые можно употребить не только в соответствии со стандартом.

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

Функция ABS - аналогична SQR, естественно без округления.

Функция RND - если аргумент плавающий, работает стандартно в отличие от случая с целым аргументом, который описан ниже.

Если функция вызвана как RND(M), где М - целое выражение, она возвращает строго случайное, равномерно распределенное целое число в интервале от 0 (включительно) до M (исключительно), положительное или отрицательное в зависимости от знака М.

Все функции работы с файлами, как уже упоминалось в главе второй, возвращают целые значения.

3.2.4. Строковые выражения

Строковые выражения могут иметь вид либо строковой константы, либо строковой переменной, либо строковой функции, либо того, другого и (или) третьего, соединенного знаком конкатенакции +.
Строковые операции полностью соответствуют стандарту MSX и поэтому здесь не рассматриваются.

3.2.5. Внешние подпрограммы и функции

Внешние подпрограммы и функции являются расширением оператора MSX BASIC CALL

Подпрограммы вызываются так:

Последний оператор может использоваться как функция внутри числового выражения. Внешние функции совместимы с C, причем параметры и возвращаемый результат должны описываться как int либо unsigned, т.е. иметь длину 2 байта.

3.2.6. Функции, определяемые пользователем

Как и MSX BASIC, так и данный компилятор позволяют определять небольшие однострочные подпрограммы–функции отдельно от основного текста программы при помощи оператора DEF FNx

DEF FN< ид_символ > [(список_параметров)]=<текст>

Список параметров может включать до 16 выражений, разделенных запятыми. Идентификаторы параметров локальны и могут иметь такие же имена, как переменные внутри основной программы. Но в отличие от интерпретатора, внутри такой функции можно использовать переменные и массивы основной программы, если их имена не совпадают с именами формальных параметров:

DIM TT(10)
… …
DEF FNA(I)= TT(I) AND &h33

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

3.3. Управляющие операторы

3.3.1. Номенклатура управляющих операторов

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

Эти операторы полностью соответствуют ГОСТ и стандарту MSX (интерпретатору), но учитывая их особенную значимость для программирования ниже будет дано достаточно подробное описание каждого из них. Операторы прерывания, как особо важные и специфические, выделены в особую главу.

3.3.2. Операторы перехода

GOTO <метка> — безусловный переход на строку с номером <метка>. Если строки с указанным номером не существует, то ошибка диагностируется только на этапе ассемблирования.
ОN <выражение> GOTO <метка>,<метка>, … — после вычисления значение выражения приводится к целому и происходит переход на строку, номер которой в списке стоит на соответствующем по порядку месте. При выходе за пределы возможных значений или если соответствующий номер строки отсутствует, выполнение программы продолжается со следующего оператора.

В упомянутых операторах вместо слова GOTO можно употребить GOSUB, при этом переход будет осуществляться на подпрограмму, выход из которой осуществляется оператором RETURN

3.3.3. Оператор ветвления

Синтаксис этого оператора:

IF <выражение> GOTO <метка>

или

IF <выражение> THEN <oператоры>[ ELSE <операторы>]

Если во второй форме сразу после ключевых слов THEN или ELSE должен стоять оператор безусловного перехода, то ключевое слово GOTO можно опустить, т.е. писать сразу номер строки.

3.3.4. Операторы циклов

FIXME

Существует два вида циклов: с заданным числом повторений и с неизвестным заранее числом повторений. Оба типа циклов реализованы в данным транслятором. В первом случае используются операторы FOR и NEXT, а во втором — WHILE и WEND со следующим синтаксисом:

FOR <переменная>=<начало> ТО <конец> STEP <приращение>

Начальное значение присваивается переменной, являющейся счётчиком цикла, после чего выполняется тело цикла. Затем к счётчику прибавляется значение приращения и результат сравнивается с конечным значением. Если значение счётчика больше при положительном приращении или меньше при отрицательном, то выполнение цикла прекращается. В любом случае тело цикла выполняется по крайней мере один раз.

NEXT [<переменная>[,<переменная>...]]

последний оператор цикла. При отсутствии переменных закрывает последний цикл, при наличии нескольких — эквивалентен последовательности из нескольких операторов NEXT подряд. Попытка закрыть внешний цикл раньше внутреннего вызывает ошибку.

WHILE <выражение>

начало цикла с неизвестным числом повторений. Цикл выполняется до тех пор, пока <выражение> не равно нулю. Тело цикла может не выполняться ни одного раза.

Этот оператор является очень мощным средством рационализации кода программ, но так как его применение достаточно сложно, он рекомендуется только очень опытным программистам.

Пример применения оператора:

WHILE ( {A%={B%=B%-1}>0} ): … … :WEND

Здесь происходит B% итераций цикла WHILE, причём в каждой из них переменная А% содержит значение истинности для условия продолжения цикла.

WEND — конец цикла WHILE. Закрывает самый вложенный цикл.

Глава 4. Ввод–вывод

Компилятор BASIC включает в себя полную систему ввода и вывода в соответствии с требованиями системы MSX. Операторы ввода-вывода полностью стандартны и поэтому ниже не будет дано их полное описание, а они будут просто перечислены, с краткими комментариями при надобности.

Определены также следующие функции:

Глава 5. Графика

5.1. Графические операторы

FIXME

Компилятор поддерживает все графические операторы:

PSET ( X , Y ) [,цвет ][,лог ]
PRESET ( X , Y ) [,цвет ][,лог]
поставить точку
LINE [(X1,Y1)] - [STEP](X2,Y2) [,цвет][,{| B | BF}][,лог]
PAINT (X,Y)[,цвет1][,цвет2];
CIRCLE (X,Y),радиус [,цвет][,нач.угол][,кон.угол][,сжатие]
COPY
во всех вариантах
DRAW <командная строка>
функция POINT(X,Y)возвращает цвет точки

Все эти операторы полностью совместимы с MSX, и подробнее об особенностях их применения и значении параметров можно узнать в любом руководстве по MSX BASIC, например, здесь

Логические операции те же, что и в MSX BASIC 2.x (для MSX 2): PSET, PRESET, AND, OR, XOR с и без префикса Т. Они имеют смысл и действие только в экранных режимах MSX 2 SCREEN 5…8.

5.2. Спрайты

Полностью соответствуют MSX-спецификации; ниже приведен список операторов, которые контролируют спрайты. Подробные сведения об их использовании можно получить из литературы по MSX 1 и MSX 2, например здесь и здесь.

SPRITE$ ( N ) = <строка>
COLOR SPRITE( N ) = <число>
COLOR SPRITE$( N ) = <строка>
PUT SPRITE <номер>,(X,Y) [,цвет][,шаблон]

Определено также прерывание ON SPRITE GOSUB, возникающее при спрайтовых коллизиях. Операторы COLOR SPRITE могут работать только на MSX 2 в экранных режимах выше 3.

5.3. Вывод текста на графический экран

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

Для машин, оборудованных Kanji ROM (это все японские MSX 2), можно применить оператор PUT KANJI:

PUT KANJI [[STEP](X,Y)],<номер кода>,[,цвет1][,цвет2][,PG]

где

Вниманию русскоязычных: Kanji ROM содержит не только японскую тарабарщину, но и все символы латинского, греческого и русского алфавита, причём есть даже буквы «ё» и большой твердый знак «Ъ».

5.4. Цвета

Цвета устанавливаются при помощи семейства операторов COLOR. Эти операторы позволяют задавать логические цвета на экране и палитру каждого из цветов.

COLOR <передний план>,<задний план>,<бордюр> — Задает цвет (логический). Любые из параметров здесь могут отсутствовать, при этом соответствующий цвет не будет изменен.

COLOR=NEW или COLOR (без параметров) — инициализирует палитру, цвета приводятся к стандартным в MSX.

COLOR=RESTORE — восстанавливает палитру из PT видеопамяти.

COLOR=(<цвет>, R, G, B) — задание палитры RGB для цвета <цвет>.

Операторы, отличные от первого в данном списке будут работать только на MSX 2, MSX 2 +.

Глава 6. Операторы системных установок

6.1. Область применения

FIXME

Операторы системных установок предназначены для реализации различных операций непосредственно связанных с аппаратным обеспечением MSX и делятся ниже на операторы для работы с экраном, LSI-SC, памятью и портами ВВ.

6.2. Работа с экраном

FIXME

SCREEN — устанавливает экранный режим и другие параметры системы. Имеют смысл все его параметры, все они полностью стандартны, поподробнее здесь.

VDP(n) — псевдопеременная, соответствующая регистру VDP n; n обозначает следующее:

Доступ к регистрам статуса 1…9 (только чтение) осуществляется как VDP(-1)…VDP(-9).

BASE(n) — псевдопеременная, содержащая базовые адреса VRAM и позволяющая их изменять. Запись возможна только в переменные с индексами от 0 до 19.

SET ADJUST (X,Y) — сдвигает экран на -8..+7 точек по вертикали и горизонтали.

SET SCROLL X,Y,<маска>, <2 стр> — проводит ролик по вертикали (MSX 1, MSX 2) и горизонтали MSX 2 +. X может иметь значение от 0 до 511, Y от 0 до 255. Если <маска> не 0, то ролик дискретный, 8 линий по Y и 8 точек по X (16 для SCREEN 6 и 7). <2 стр> имеет смысл только на MSX 2 + и означает горизонтальный скроллинг по горизонтали через 2 соседние страницы VRAM (позволяет увеличить «ширину» окна).

SET PAGE <активная>[,<дисплей>] — установка страниц VRAM в режимах 5…8 (12). Если номер дисплейной страницы не указан, он полагается равным номеру активной страницы.

6.3. Работа с системной микросхемой "100 ног" (LSI-SC)

FIXME

Системный контроллер MSX 2 (MSX-SYSTEM) включает: звукогенератор PSG, часы реального времени, независимую память с батарейным питанием. Для работы с ними можно употреблять такие операторы:

SOUND <регистр>, <значение>
запись байта в регистр PSG
BEEP
подача сигнала
SET BEEP <тип>, <громкость>
установка параметров сигнала BEEP (числа в интервале 1…4 ), не работает на MSX 1
SET TIME <строка>[,a]
запись времени в часы
GET TIME <переменная>[,a]
чтение времени из часов
SET DATE <строка>[,a]
запись даты в часы
GET DATE <переменная>[,a]
чтение даты из часов

6.4. Работа с памятью и портами

CLEAR <длина строковой памяти>, <макс. адрес>
можно применять только в самом начале главной программы, так как оператор изменяет положение стека
MAXFILES = N
изменяет число доступных LUN для файловой системы BASIC. Очищает файловые дескрипторы, FCB и буфера
PEEK(адрес)
читает содержимое памяти по адресу
POKE <адрес>,<значение>
пишет в память. Следует соблюдать осторожность, чтобы не записать данные на программу при слишком маленьком адресе
INP(порт)
вводит байт из порта ввода
OUT <порт>,<значение>
выводит байт в порт
WAIT <порт>,<маска И>, <маска XOR>
ждёт ненулевого результата выражения
INP(порт) AND <маска И> XOR <маска XOR>

при разрешенных прерываниях

Глава 7. Прерывания

MSX BASIC включает несколько групп прерываний: таймерное, от аппаратных средств, от клавиши CTRL+STOP и от ошибки.

Для всех прерываний процедура использования одинакова: сначала нужно определить программу-обработчик оператором ON xxxx GOSUB, а затем разрешить прерывания оператором xxxx ON. Впоследствии можно запрещать прерывания оператором xxxx OFF или приостанавливать их xxxx STOP.

ОN KEY GOSUB <a1>,… <a10> , KEY (#) ON|OFF|STOP

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

ON STRIG GOSUB <a1>,… ,<a5>, STRIG(#) ON|OFF|STOP

Прерывание происходит по нажатии кнопки пультов или пробела

ON INTERVAL=<N> GOSUB <a>

каждые <N> таймерных тиков (1/60 сек.) происходит прерывание

ОN SPRITE GOSUB

происходит прерывание при обнаружении наложения спрайтов

ОN STOP GOSUB

вызывает прерывание по нажатию CTRL+STOP.
При этом остановки программы не происходит. STOP OFF вообще отключает возможность остановки программы CTRL+STOP, STOP ON разрешает её, но и прерывание тоже (если оно было установлено ранее.)

ON ERROR GOTO

определяет программу обработки ошибок, возврат из этой программы осуществляется оператором RESUME

Часть III. Руководство системного программиста.

Глава 1. Формат входных и выходных файлов

Входной текст представляет программу на языке MSX BASIC в текстовом (ASCII) представлении с длиной строки до 254 символов. Строки могут нумероваться только при надобности, строки на которые нет ссылок, можно не нумеровать. Порядок следования номеров строк также произвольный, но не должно встречаться нескольких строк с одинаковым номером. Если строка оканчивается строковой константой, допустимо не ставить закрывающей кавычки, однако это рекомендуется делать.

При чтении исходного текста повсюду в тексте, кроме строковых констант, буквы преобразуются в большие латинские. Разборка на операторы происходит построчно, при этом в качестве очередного оператора берется минимальная подстрока из очередной лексемы, где лексема — часть однородных А/Ц символов, ограниченная каким-либо разделителем. Разделителями являются: конец строки, пробел, все специальные символы, а также при разборке числа — любой другой символ, не соответствующий набору возможных в данном числе символов.

Оператор комментария должен быть последним или единственным в строке. Любой текст после комментария игнорируется.

Выходной результат трансляции — файл на ассемблере Z80, состоящий из: заголовка, тела программы, дампа переменных и дампа строк. Дамп переменных объявлен как DSEG, остальные части программы — как CSEG, что позволяет на этапе сборки выносить зону переменных в любое удобное место. Рассмотрим входной и выходной результаты трансляции на примере маленькой программы. Итак, имеем на входе файл TEST со следующим содержимым:

TEST.BAS
pragma source
A=1:B=A+1'this is remark
print "A=";b

Вызываем компилятор:

a>VBC TEST.BAS
SOLID SOFT BASIC compiler V2.0vx
....
....
complete.

Так как в программе указана опция SOURCE, текст программы распечатывался на экране, а также в качестве комментариев включался в объектную программу на ассемблере.

ТЕST.ASM
; Solid Soft BASIC compiler V2.0 <- версия компилятора.
	.Z80
;
	CSEG    <------------ Конец заголовка.
;
;A=1:B=A+1'THIS IS REMARK: <- исходный текст
	ld	hl,00001h  <- программа
	ld	(@A ),hl
	inc	hl
	ld	(@B ),hl
;
;PRINT"A=";B:
	call	?FINIT##   <- Инициализация строк
	ld	hl,?CONST+00000h
	call	?LDSTR##   <- Получение константы
	ld	hl,(@B )
	call	?FSTRX##
	call	?INCLF##
	ld	de,00000h  <- Номер канала PRINT
	call	?PRINT##
;:
;
	ret                  <- конец программы
	DSEG                 <- зона данных
 
@A:	ds	00002h       <- переменные
@B:     ds      00002h
	CSEG  <---------------- Опять сегмент кода
?CONST:                      <- зона констант
	db	041h,03Dh,000h,00h  <- текст "A=\0"
	END                  <- конец файла

Зона строковых констант является сегментом кода, что соответствует соглашению по MSX ASCII C 1.0. Так как рекомендованным сборщиком для MSX BASIC является LINK, зона констант подклеивается к соответствующей программе, а зоны данных, т.е. переменные всех модулей выносятся в конец COM–файла. Работать с L80 не рекомендуется, так как он не инициализирует конструкции DS и поэтому может произойти накладка со строковыми переменными.

Глава 2. Форматы данных на этапе исполнения

Программы используют три типа данных — целые, плавающие и строковые. Все операции с плавающими числами производятся с двойной точностью, поэтому одинарная точность — лишь способ хранения в памяти, но не тип данных. Данные представляются в следующих форматах:

Глава 3. Файловые буфера

Для оптимизации дискового ввода-вывода, а также для совместимости с MSX-интерпретатором в откомпилированной программе используется буферизованный ввод–вывод. При этом каждому каналу соответствует свой буфер с соответствующими системными зонами. Зоны эти таковы:

9 байтFCB, совместимый с MSX BASIC
256 байтфайловый буфер
38 байтDOS FCB

Формат FCB для MSX BASIC стандартен:

+0: МODрежим файла (0 — не открыт, 1 — чтение, 2 — запись, 4 — прямой, 8 — добавление)
+1: DOSFCссылка на DOS FCB
+3: LENдлина блока для режима 4; 0 == 256 байт.
+4: DEVкод устройства ( 0…8 для дисков, FCh…FFh для GRP:,CRT:,LST:
+6: POSпозиция в файловом буфере
+8: PPSпозиция PRINT, возвращается функцией FPOS

Формат DOS FCB стандартный для MSX-DOS 1.03 (38 байт — для функций прямого чтения-записи)

Файловая система использует вызовы DOS 26h, 27h для записи и чтения. При прямой записи/чтении длина блока соответствует длине указанной при открытии файла и обмен происходит по 1 блоку. При последовательном доступе длина блока — 1 байт и обмен идет по 256 блоков.

Библиотека подразумевает, что файлы прямого доступа — двоичные, а последовательные — текстовые. Поэтому при закрытии файла, открытого FOR OUTPUT или FOR APPEND, в конец его дописывается символ <EOF> (26h), и добавление в конец файла FOR APPEND осуществляется не с конца файла, а с момента первой встречи символа <EOF>.

Глава 4. Использование ресурсов

Компилятор и его библиотеки построены так, что легально используют все ресурсы MSX-компьютера. Возможно, это снижает производительность, но зато дает гарантию против конфликтов с различными системными программами. Для сокращения объёмов библиотек широко используется ROM BIOS и MSX-2 SUB-ROM.

Известно, что вызовы SUB-ROM на компьютерах в некоторых конфигурациях вызывает сбои. Это происходит, в частности, на комплекте 503 + FD-051 из–за неправильно написанного дискового ПЗУ. Для ликвидации этого недоразумения в комплект поставки входит программа SLOT(© Ф.Вагапов, 1989) для эмуляции нормального переключения слотов. Эту программу достаточно запустить один раз при начальной загрузке. SLOT — некоммерческая программа, она может быть беспрепятственно скопирована и использована для любых приложений.

Все функции управления экраном, за исключением SET SCROLL, обращаются к ПЗУ компьютера и осуществляют интерфейс с аппаратурой, строго соблюдая спецификации MSX. Режимы SCREEN 10,11,12 на MSX 2 + включаются также на аппаратном уровне.

Глава 5. Оптимизация

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

Выходной ассемблер имеет команды Z-80, что позволяет в некоторых случаях даже без оптимизации получать более оптимальный код, нежели код от транслятора MSX-C.

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

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

Оптимизация гарантирует сжатие кода целочисленных и управляющих конструкций не менее чем 1,3…2 раза по сравнению с неоптимизированным кодом.

Неоптимизированный код по качеству соответствует коду ТУРБО-ПАСКАЛЯ или AZTEK-C и чрезвычайно медленный, из–за обилия стековых операций.

В результате оптимизации НЕ ГАРАНТИРУЕТСЯ ПОРЯДОК ВЫЧИСЛЕНИЯ, поэтому, если требуется точный порядок вычислений, оптимизатор можно выключить.

Кроме того, рекомендуется отключать оптимизатор при первой трансляции длинных программ, так как в таких программах наверняка найдутся ошибки, а без оптимизатора программа будет оттранслирована значительно (в 2…3 раза) быстрее.

Оптимизатор включается и выключается при помощи операторов PRAGMA и имеет 3 уровня оптимизации:

Результат тестовых прогонов
При отключённом листинге и выводе исходного текста компилятор имеет следующие параметры:

Качество кода проверялось вручную, т.е. смотрелась возможность замены конструкций на более оптимальные по скорости и занимаемой памяти для небольшой циклической программы, содержащей основные операторы языка и работу над массивами в цикле.

Касательно скорости компиляции следует заметить, что большие программы даже если и компилируются быстро, то линкуются чрезвычайно медленно. Так, программа в 530 строк на MSX BASIC (правда чрезвычайно сложная и с большим количеством ввода-вывода и строковых операций) линковалась редактором LINK в течение 17 минут.

Сравнение с MSX BASIC
При прогоне программы в целых числах, с выводом на экран и строковыми операциями во вложенных циклах большой длительности компилятор показал скоростные характеристики 7:1…(9:1) без (при) оптимизации. При выполнении программы без вывода это соотношение намного больше (30:1…50:1).

Глава 6. Раздельная компиляция

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

Оператор PROCEDURE, синтаксис:

PROCEDURE <name>

Объявляет последующий код до конца файла либо до следующего оператора PROCEDURE подпрограммой с глобальным именем <name>. Имя <name> соответствует соглашению об именах МSX-C.
Процедуры в одном файле разделяют все переменные, и не надо объявлять их внешними или глобальными.

Оператор GLOBAL, синтаксис:

GLOBAL <var1> [,<var2> ...]

Определяет переменные <var1> … глобальными.

Оператор EXTERN, синтаксис:

EXTERN <var1> [,<var2> ...]

Определяет переменные <var1> … внешними. Они должны быть также объявлены глобальными в другом модуле программы, но не в этом же файле.

Оператор PRAGMA, синтаксис:

PRAGMA <параметр>
<параметр>::={OPTIMIZE,NOOPTIMIZE,LIST,NOLIST,SOURCE,VECT
                NOVECT,NOSOURCE,WORD_DATA,BYTE_DATA}

Определяет режим работы компилятора:

ПРИМЕЧАНИЕ: PRAGMA SOURCE вызывает вывод листинга и на экран.

Устанавливаются по умолчанию: VECT, OPTIMIZE, NOLIST, NOSOURCE.

Приложение А. Список функций, имеющихся в данной реализации

Функции плавающей арифметики:

Целочисленные функции:

Функция USR при обращении к адресам менее 8000h переходит к ROM BIOS, иначе обращение идет к памяти ОЗУ. USR может принимать один целый аргумент через HL и так же возвращает результат. Функции ABS, SQR, RND описаны в II — 3.2.3.

Строковые функции:

Приложение B. Наиболее вероятные причины ошибок

Ниже будут приведены основные причины возникновения пяти самых часто встречающихся ошибок.

Syntax error — Очень часто встречается, иногда второй ошибкой после какой–нибудь другой. В этом случае она исчезает по удалении первой ошибки. Кроме того часто встречается при трансляции BASIC–программ, из которых удалены все пробелы между операторов. Способ исправления — поставить где необходимо пробелы.

Type mismatchЧаще всего встречается при совпадении имён переменных разных типов (см. II — 1.3, 3.1). Способ исправления — переименовать совпавшие переменные
Bad parameterСледует проверить соответствие синтаксиса оператора стандарту. Может возникнуть при объявлении массива с размерностью больше двух
Assignment to FIELDПопытка присвоить значение полю FIELD при помощи обычного присвоения. Следует заменить его на LSET
Undefined arrayпри попытке использовать массив, объявленный по умолчанию, что невозможно в данном компиляторе. Следует объявить массив заранее

Приложение C. Комплект поставки

В комплект поставки входят следующие файлы на диске:

BAS.BATпакетный файл для нормальной компиляции
VBC.COMкомпилятор BASIC
M80.COMассемблер
LINK.COMредактор связей
SLOT.COMпрограмма для исправления ошибок SLOT CALL
BASIC.DOCданное руководство
BK.RELядро компилятора
ILIB.RELглавная часть библиотеки
BASEND.RELфайл окончания
BITBLT.RELфайл подпрограмм BITBLT (его нужно употреблять, если в программе использованы операторы COPY)
SAMPLE.BASтексты демонстрационных программ

Ссылки

BASIC и Assembler с возможностью работы в Nextore DOS

Недооцененные возможности MSX Basic

SOLiD homepage: MSX Warez Stock

Novatec Archive - categories