V. B. C. MSX-совместимый компилятор БЕЙСИКА Руководство пользователя Руководство программиста Руководство системного программиста * * * V. B. C. MSX-compatible BASIC compiler User guide Programmer's guide Advanced programmer's guide =========================================================== Что такое VBC I-1 ------------------------------------------------------------ Часть I Руководство пользователя Глава 1. Что такое VBC ? -------------- Компилятор создавался с целью получения языка, максимально приближенного к MSX - бейсику. Более того, поскольку возможна отладка с помощью интерпретатора, из компилятора исключена диагностика некоторых ошибок, которые можно выявить в процессе отладки на интерпретаторе. Входной язык представляет собой несколько расширенную версию MSX - BASIC , состоящую из ядра и расширенную следующими функциями: - оператор цикла WHILE - WEND (эквивалентен таковому в IBM - бейсике (BASICA,GW-BASIC). - средства поддержки раздельной компиляции (PROCEDURE, расширение оператора CALL, совместимость с MSX-C. - опция управления компилятором PRAGMA. Глава 2. Как запускать компилятор ------------------------ Если у вас есть уже готовая программа на бейсике , то чтобы ее оттранслировать достаточно лишь набрать команду: A>BAS <имя файла> [ввод] При этом подразумевается, что файл имеет расширение BAS. Если при трансляции не возникнет ошибок, то вы станете обладателем COM-файла с именем исходного файла, содержащего вашу программу в оттранслрованном виде. Ее можно сразу запустить. Для более любознательных сообщаю, что компилятор можно запустить и без BAT-файла командой A>VBC <имя файла>. [/C] Имя файла нужно указать полное, с расширением. Необязательный ключ /C указывает компилятору, что нужно произвести только проверку синтаксиса, без создания выходного файла. Kaк запускать компилятор I-2 ------------------------------------------------------------ При работе компилятор сообщит вам свою версию, может напечатать листинг программы ( для этого следует включить в текст программы операторы PRAGMA LIST), а в конце работы - распечатает список всех обьявленных переменных и количество обнаруженных ошибок. Если ошибок не было обнаружено, выводится сообщение "complete." Совместимость II-1 ------------------------------------------------------------ Часть II Руководство программиста Глава 1 Совместимость со стандартами ---------------------------- 1.1. ГОСТ-совместимость Входной язык компилятора полностью включает в себя ЯДРО и расширен в соответствии с УРОВЕМ1 и УРОВНЕМ2 расширения. Кроме того, он поддерживает ряд опций, не предусмотренных в ГОСТ, а именно: - средство управления компиляцией PRAGMA; - средств для подержки раздельной компиляции: EXTERN,GLOBAL,PROCEDURE; - логические операции AND и OR в операторах IF могут быть условными; - можно нумеровать только строки, к которым есть ссылка; - реализован механизм присваивания, аналогичный таковому в языке C - присваивание по цепочке. Кроме того, часть возможностей, специфицированных в расширенных модулях ГОСТ не реализована в связи с изменением модели распределения памяти времени компиляции (см. п.1.3). 1.2. Совместимость с MSX. Компилятор соответствует MSX-BASIC, с учетом пп. 1.1 и 1.3 и включает в себя: - математические возможности - полностью; - работу с памятью - все, кроме ERASE; - графику - полностью *); - музыкальные возможности - согласно спецификации SSG *); - спрайты - полностью; - ввод-вывод - полностью, с исключениями согласно п. 1.3; - управляющие операторы: все, добавлен цикл WHILE, исключение: неопределен результат RESUME без параметров; Соответствие MSX-2 стандарту: - графика - полностью *); - системные функции: COPYSCREEN,GET/SET TIME/DATE, SET BEEP/ADJUST, PUT KANJI; - функции работы с палитрой. Совместимость II-2 ------------------------------------------------------------ Соответствие MSX-2+ стандарту: - режимы SCREEN 10,11,12 ( YJK - графика ) - SET SCROLL - доступ к регистрам S1 .. S9 видеопроцессора Примечание: *) - звездочкой отмечены полностью совместимые с MSX стандартом разделы в которых имеется, однако, одно исключение: в макроязыке операторов DRAW и PLAY не определен параметр X (смотри руководство по MSX- бейсику), что обусловлено особенностями работы откомпилированной программы с памятью. Функции, соответствующие более позднему MSX стандарту, могут быть реализованы на машине более раннего стандарта при условии наличия необходимых аппаратных средств и (или) BIOS. Например SETSCROLL можно выполнять на всех компьютерах с V9938, но при этом скроллинг будет только по вертикали. Часть операторов (например SET PASSWORD или SET VIDEO), не реализованы или как не имеющие смысла в откомпилированной программе или как редко употребляемые. Их при необходимости можно эмулировать соответствующими комбинациями OUT'ов. 1.3. Отходы от стандартов Отходы от стандартов обусловлены оптимизацией получаемого кода и невозможностью реализации части функций в модели компилируемой программы. Эти отходы перечислены ниже: - Все функции ввода/вывода а также внешние функции получают и возвращают параметры только целого типа, например номер записи в операторах GET/PUT должен быть 1..65535; - Память под массивы и переменные выделяется 1 раз при компиляции, поэтому оператор ERASE не определен, CLEAR очищает только строки и файлы и при обьявлении массивов для указания размерностей следует использовать ТОЛЬКО константы. - Массивы могут быть одномерные или двумерные - это досадное недоразумение, которое легко обойти, проэмулировав массив большей размерности. - Типы переменных жестко связаны с именами. Нельзя, например использовать в одной программе A и A$, a также массив с именем, совпадающим с именем простой переменной. Подробнее об этом в главе 3. - Пробелы в тексте программы ЯВЛЯЮТСЯ разделителями. - При разборе текста в качестве имени переменной берется строка до ближайшего разделителя, поэтому возможны синтаксические ошибки в работавших на интерпретаторе программах, например: FORI=LTO100:.... даст Syntax error. Чтобы ошибки не было, следует применить скобки либо после имени переменной ставить пробел: FORI=(L)TO100 или FOR I=L TO100 Для облегчения адаптации программ в конце данного руководства помещен список ошибок и возможные их причины. Преимущества компилятора II-3 ------------------------------------------------------------ Глава 2 Преимущества компилятора IBAS ----------------------------- Главным преимуществом откомпилированной программы является во много раз большая скорость ее исполнения, что особенно заметно при целочисленных операциях. В данном случае мы имеем ускорение вычислений в 20..50 раз по сравнению с интерпретатором в зависимости от типа программы. (это для целых чисел). Скорость вычислений с плавающей точкой возрастает в 1.3 .. 2.5 раза в основном за счет операций загрузки / записи. Скорость выполнения строковых операций зависит от типа операции, но в целом немного выше, чем в интерпретаторе. Особенно быстро выполняются короткие циклы в целых числах с вычислением массивов внутри них. Компилятор снабжен мощным оптимизатором и ориентирован на написание программ управляющего характера, в связи с чем в нем основным типом данных являются целые числа. Такие популярные функции, как RND и SQR имеют версии для целых аргументов, возвращающие также целое число и чрезвычайно быстродействующие. Деление при применении к двум целым также возвращает целое т.е. a% / b% = a% \ b% . Компилятор совместим с MSX-ASCII-C при вызове из бейсика внешних подпрограмм. Кроме того он имеет средства раздельной компиляции модулей, написанных на бейсике. Что касается скорости компиляции, то она несколько превосходит скорость компиляции аналогичной программы компилятором MSX-C, а за счет использования некоторых ухищрений при оптимизации и специфических команд процессора Z80 оптимальность получаемого кода не меньше, а местами даже больше, чем у семантически аналогичной программы, написанной на C и откомпилированной компилятором ASCII. На выходе компилятора получается программа на ассемблере в мнемонике Z80, что также лучше, чем мнемоника 8080 на выходе ASCII-C. При желании квалифицированный программист может внести изменения уже в файл ассемблера. Для облегчения таких работ у компилятора имеется опция, позволяющая вводить исходный текст программы на бейсике в выходной файл в виде комментариев. Библиотека компилятора обеспечивает достаточно быструю работу с файлами и имеет несколько функций для доступа к ресурсам ОС, позволяющих легко писать системные утилиты с современным, графическим интерфейсом. В общем, данный компилятор является на данный момент практически единственным компилятором, собирающим в себе все возможности и на таком уровне совместимый со стандартом MSX. Ядро компилятора II-4 ------------------------------------------------------------ Глава 3. Ядро компилятора ---------------- 3.1. Переменные и массивы Переменные и массивы идентифицируются по имени, причем оно может быть произвольной длины. В соответствии со стандартом на бейсик, имена различаются по первым двум символам, первый из которых должен быть латинской буквой, а второй - буквой или цифрой. Не допускается использование русских букв и графических символов. Строчные латинские буквы переводятся в прописные. Сразу после имени переменной может стоять необязательный символ типа: % - для целой переменной; $ - для символьной переменной; ! - для переменной одинарной точности; # - для переменной двойной точности. Если таковой не стоит, то тип переменной определяется по первому символу имени переменной в соответствии с оператором DEF, имеющему вид: DEF { INT | STR | SNG | DBL } <символ>[- <символ>] ... где INT,STR,SNG,DBL обозначают соответственно целый, символьный, одинарный и двойной типы, а <символ> - первый символ имени переменной. Конструкция <символ А>-<символ Б> означает "от А до Б включительно". !:В отличие от MSX-BASIC по умолчанию все переменные определены как целые, поэтому следует в программах первой строкой вставить DEFDBL A-Z. Напротив, конструкцию типа DEFINT A-Z можно опустить. Здесь имеется и еще одно отличие от стандарта MSX : как переменные всех типов, так и массивы в компиляторе распознаются и с к л ю ч и т е л ь н о по двум первым символам, в результате чего возникают ошибки в программе в следующих ситуациях: - если в программе обьявлены в разных местах переменные одинакового имени, но с разным постфиксом точности: А и А$ , X и X# ; - если аналогичное произошло с массивом и простой переменной; Кроме того, нельзя использовать массивы, обьявленные по умолчанию. Тип переменной устанавливается компилятором один раз при первой встрече согласно правилам, описанным выше, и остается неизменным на протяжении всей программы, поэтому символ точности можно указывать только один раз, что экономит текст программы и избавляет пользователя от возможных ошибок в результате пропуска такого символа в программе. Ядро компилятора II-5 ------------------------------------------------------------ Все перечисленные отличия от стандарта MSX не являются прямыми противоречиями ГОСТ и введены для улучшения стиля программ, написанных на БЕЙСИКе. 3.2. Выражения 3.2.1. Математические выражения В выражениях можно применять следующие операции, причем в следующем приоритете (начиная с наинизшего) : - операция инверсии "логическое не" - NOT <выражение> NOT инвертирует все биты в значении выражения, стоящего после него. Если тип выражения отличен от целого, он приводится к целому. - логические операции AND, OR, XOR, EQV Это двуместные операции; производятся побитно, за исключением операций AND, OR в операторе IF. В последнем случае, если такие операции связывают два или более выражения отношения, они выполняются условно, т.е. до тех пор, пока не будет окончательно ясен результат операции. Операция EQV соответствует NOT XOR. Операции возвращают целый результат. Оба аргумента приводятся к целому типу. - операции отношения > < = <> >= <= Это двуместные операции, возвращающие целый результат в следующем виде: истине соответствует -1,ложному результату 0 Аргументами операции могут быть целые, плавающие числа и строковые выражения, причем числовые выражения приводятся к более точному типу, а более короткие строки считаются меньшими, чем более длинные при совпадении первых символов. Сравнивание строки с числом не допускается. - операции сложения и вычитания +,- - операции умножения и деления *, /, \, MOD Oперация "/" при применении к двум целым возвращает целый результат, т.е. работает аналогично "\". Операции "\" и "MOD" преобразуют оба аргумента в целый тип. MOD возвращает остаток от деления. - операция возведения в степень ^ - операция смены знака - (одноместная) - операции в скобках и оператор присваивания (см 3.2.2) - функции (см 3.2.3) 3.2.2. Оператор присваивания. Оператор присваивания имеет вид: [ LET ] { переменная | массив } = <выражение> Если такой оператор заключить в фигурные скобки, его можно использовать в выражениях следующим образом: Если присваивается целое целой переменной, то результатом будет это число. Если присваивается число с плавающей точкой (не важно, чему), то результатом будет это число. Ядро компилятора II-6 ------------------------------------------------------------ Во всех остальных случаях результатом будет адрес переменной или массива, куда произошло присваивание. Этот оператор является очень мощным средством рационализации кода программ, но так как его применение достаточно сложно, он рекомендуется только очень опытным программистам. пример применения оператора: WHILE ( {A%={B%=B%-1}>0} ): ..... :WEND Здесь происходит B% итераций цикла WHILE, причем в каждой из них переменная А% содержит значение истинности для условия продолжения цикла. 3.2.3 Функции. В математических выражениях можно употреблять функции, определенные в МSX, причем их действие стандартно, поэтому здесь будут полно описаны лишь три функции, которые можно употребить не только в соответствии со стандартом. Функция SQR Eсли ее аргумент плавающее число, то результат плавающий, если же аргумент целый, то и результат целый, округленный до ближайшего меньшего. Функция ABS - аналогична SQR, естественно без округления. Функция RND - если аргумент плавающий, работает стандартно в отличие от случая с целым аргументом, который описан ниже. Если функция вызвана как RND(M), где М - целое выражение, она возвращает строго случайное, равномерно распределенное целое число в интервале от 0 (включительно) до M (исключительно), положительное или отрицательное в зависимости от знака М. Все функции работы с файлами, как уже упоминалось в главе второй, возвращают целые значения. 3.2.4. Строковые выражения Строковые выражения могут иметь вид либо строковой константы, либо строковой переменной, либо строковой функции, либо того, другого и (или) третьего, соединенного знаком конкатенакции +. Строковые операции полностью соответствуют стандарту MSX и поэтому здесь не рассматриваются. Ядро компилятора II-7 ------------------------------------------------------------ 3.2.5. Внешние подпрограммы и функции. Внешние подпрограммы и функции являются расширением оператора MSX-BASIC CALL. Подпрограммы вызываются так: CALL <имя> ( список параметров ) _ <имя> ( список параметров ) Последний оператор может использоваться как функция внутри числового выражения. Внешние функции совместимы с C, причем в случае передаци параметров и возврата результата они должны описываться как int либо unsigned, т.е. иметь длину 2 байта. 3.2.6. Функции, определяемые пользователем. Как и MSX-интерпретатор, так и данный компилятор позволяют определять небольшие однострочные подпрограммы-функции отдельно от основного текста программы при помощи оператора DEF FNx: DEF FN< ид_символ > [(список_параметров)]=<текст> Список параметров может включать до 16 выражений, разделенных запятыми. Идентификаторы параметров локальны и могут иметь такие же имена, как переменные внутри основной программы. Но в отличие от интерпретатора, внутри такой функции можно использовать переменные и массивы основной программы, если их имена не совпадают с именами формальных параметров: DIM TT(10) ..... DEF FNA(I)= TT(I) AND &h33 При использовании пользовательских функций с большими обьемами строковых вычислений следует остерегаться переполнения строкового стека, что может дать ошибочный результат. 3.3. Управляющие операторы 3.3.1. Номенклатура управляющих операторов К управляющим операторам относятся операторы, позволяющие изменить последовательность исполнения других операторов программы с целью реализации сложных алгоритмических структур. Входной язык компилятора содержит широкий набор таких операторов, включающий операторы безусловного перехода и перехода по значению, а также операторы ветвления, цикла и прерываний: GOTO - оператор перехода; ON <выражение> GOTO - переход по знацению; IF - THEN - ELSE - оператор цикла; FOR - NEXT - операторы цикла; WHILE - WEND - операторы цикла с неизвестным числом повторений; Ядро компилятора II-8 ------------------------------------------------------------ Эти операторы полностью соответствуют ГОСТ и стандарту MSX (интерпретатору), но учитывая их особенную значимость для программирования ниже будет дано достаточно подробное описание каждого из них. Операторы прерывания, как особо важные и специфические выделены в особую главу. 3.3.2. Операторы перехода GOTO <метка> - безусловный переход на строку с номером <метка>. Если строки с указанным номером не существует, то ошибка диагностируется только на этапе ассемблирования. ОN <выражение> GOTO <метка>,<метка>,... - после вычисления значение выражения приводится к целому и происходит переход на строку, номер которой в списке стоит на соответствующем по порядку месте. При выходе за пределы возможных значений или если соответствующий номер строки отсутствует, выполнение программы продолжается со следующего оператора. В упомянутых операторах вместо слова GOTO можно употребить GOSUB, при этом переход будет осуществляться на подпрограмму, выход из которой осуществляется оператором RETURN. 3.3.3. Оператор ветвления Синтаксис этого оператора: IF <выражение> GOTO <метка> или IF <выражение> THEN [ ELSE <операторы>] Если во второй форме сразу после ключевых слов THEN или ELSE должен стоять оператор безусловного перехода, то ключевое слово GOTO можно опустить, т.е. писать сразу номер строки. 3.3.4. Операторы циклов. Существует два вида циклов: с заданным числом повторенй и с неизвестным заранее числом повторенй. Оба типа циклов реализованы в данным транслятором. В первом случае используются операторы FOR и NEXT, а во втором - WHILE и WEND со следующим синтаксисом: FOR <переменная>=<начало> ТО <конец> STEP <приращение> Начальное значение присваивается переменной, являющейся счетчиком цикла, после чего выполняется тело цикла. Затем к счетчику прибавляется значение приращения и результат сравнивается с конечным значением. Если значение счетчика больше при положительном приращении или меньше при отрицательном, то выполнение цикла прекращается. В любом случае тело цикла выполняется по крайней мере один раз. Ввод и вывод II-9 ------------------------------------------------------------ NEXT [<переменная>[,<переменная>...]] - последний оператор цикла. При отсутствии переменных закрывает последний цикл, при наличии нескольких - эквивалентен последовательности из нескольких операторов NEXT подряд. Попытка закрыть внешний цикл раньше внутреннего вызывает ошибку. WHILE <выражение> - начало цикла с неизвестным числом повторенй. Цикл выполняется до тех пор, пока <выражение> не равно нулю. Тело цикла может не выполняться ни одного раза. WEND - конец цикла WHILE. Закрывает самый вложенный цикл. Глава 4. Ввод - вывод. ------------ Компилятор бейсика включает в себя полную систему ввода и вывода в соответствии с требованиями системы MSX. Операторы ввода-вывода полностью стандартны и поэтому ниже не будет дано их полное описание, а они будут просто перечислены, с краткими комментариями при надобности. INPUT - стандартен полностью; LINE INPUT - стандартен полностью; PRINT - стандартен полностью, поддерживается форматный вывод при помощи оператора USING; INKEY$ - стандартен полностью; INPUT$( n ) - стандартен полностью, имеется и файловый вариант этого оператора: INPUT$( LUN , n ); OPEN - стандартен полностью, поддерживает системные устройства CRT: , GRP: , LPT:, при открытии дискового файла FOR OUTPUT стирает существующий, если он есть; CLOSE - стандартен полностью, при наличии вывода в файлы обязателен в конце программы; BLOAD - стандартен полностью, но нельзя делать BLOAD ,r BSAVE - стандартен полностью; GET , PUT - стандартен полностью; Определены также следующие функции: CSRLIN POS FPOS LOC LOF EOF LPOS DSKI$ DSKO$ DSKF Графика II-10 ------------------------------------------------------------ Глава 5. Графика. -------- 5.1. Графические операторы. Компилятор поддерживает все графические операторы: 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-бейсику. Логические операции те же, что и в бейсике MSX-2: PSET,PRESET,AND,OR,XOR с и без префикса Т. Они имеют смысл и действие только в экранных режимах MSX-2 SCREEN 5 ... 8. 5.2. Спрайты. Полностью соответствуют MSX-спецификации; ниже приведен список операторов, которые контролируют спрайты. Подробные сведения об их использовании можно получить из литературы по MSX и 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: и выводить на него данные. Данные выводятся с последней позиции графического курсора. Системные операторы II-11 ------------------------------------------------------------ Для машин, оборудованных KANJI - ROM (это все японские MSX2), можно применить оператор PUT KANJI: PUT KANJI [[STEP](X,Y)],<номер кода>,[,цвет1][,цвет2][,PG] где номер кода - целое двухбайтное число, каждый из байтов которого находится в диапазоне 21h .. 7Fh, а PG - признак разбиения. Если он равен 0, то выводится весь символ, если 1-четные строки, если 2- нечетные. Вниманию русскоязычных: КANJI ROM содержит не только японскую тарабарщину, но и все символы латинского, греческого и русского алфавита, причем есть даже буквы "йо" и большой твердый знак. 5.4. Цвета. Цвета устанавливаются при помощи семейства операторов COLOR. Эти операторы позволяют задавать логические цвета на экране и палитру каждого из цветов. COLOR <передний план>,<задний план>,<бордюр> - Задает цвет (логический). Любые из параметров здесь могут отсутствовать, при этом соответствующий цвет не будет изменен. COLOR=NEW или COLOR (без параметров) - инициализирует палитру, цвета приводятся к стандартным в MSX. COLOR=RESTORE - восстанавливает палитру из PT видеопамяти. COLOR=(<цвет>, R , G , B) - задание палитры RGB для цвета <цвет>. Операторы, отличные от первого в данном списке будут работать только на MSX-2, MSX 2+. Глава 6. Операторы системных установок. ------------------------------ 6.1. Область применения. Операторы системных установок предназначены для реализации различных операций непосредственно связанных с аппаратным обеспечением MSX и делятся ниже на операторы для работы с экраном, LSI-SC, памятью и портами ВВ. Системные операторы II-12 ------------------------------------------------------------ 6.2. Работа с экраном. SCREEN - устанавливает экранный режим и другие параметры системы. Имеют смысл все его параметры, все они полностью стандартны. VDP(n) - псевдопеременная, соответствующая регистру VDP n; n обозначает следующее: 0 .. 7 == R#0 .. R#7 (чтение и запись) , 8 == S#0 (только чтение), 9 .. 28 == R#8 .. R#27 (чтение и запись, R#25,R#26,R#27 имеют смысл только на машинах с VDP 9958 - MSX 2+), 33 .. 47 == R#32 .. R#46 (регистры команд, только запись). Доступ к регистрам статуса 1..9 (только чтение) осуществляется как VDP(-1) .. VDP(-9). BASE(n) - псевдопеременная, содержащая базовые адреса VRAM и позволяющая их изменять. Запись возможна только в переменные с индексами от 0 до 19. SET ADJUST (X,Y) - сдвигает экран на -8..+7 точек по вертикали и горизонтали. SET SCROLL X,Y,<маска>,<2 стр> - проводит ролик по вертикали (MSX, MSX2) и горизонтали (MSX 2+). X может иметь значение от 0 до 511, Y oт 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). Системный контроллер МSX-2 включает: звукогенератор SSG, часы реального времени, независимую память с батарейным питанием. Для работы с ними можно употреблять такие операторы: SOUND <регистр>,<значение> - запись байта в регистр SSG, BEEP - подача сигнала; SET BEEP <тип>,<громкость> - установка параметров сигнала BEEP ( числа в интервале 1 .. 4 ), не работает на MSX-1. SET TIME <строка>[,a] - запись времени в часы; GET TIME <переменная>[,a] - чтение времени из часов; SET DATE <строка>[,a] - запись даты в часы; GET DATE <переменная>[,a] - чтение даты из часов; 6.4. Работа с памятью и портами CLEAR <длина строковой памяти>,<макс. адрес> - можно применять только в самом начале главной программы, так как оператор изменяет положение стека. Прерывания II-13 ------------------------------------------------------------ MAXFILES = N - изменяет число доступных LUN для файловой системы бейсика. Очищает файловые дескрипторы, FCB и буфера. PEEK(адрес) - читает содержимое памяти по адресу. POKE <адрес>,<значение> - пишет в память. Следует соблюдать осторожность, чтобы не записать данные на программу при слишком маленьком адресе. INP(порт) - вводит байт из порта ввода. OUT <порт>,<значение> - выводит байт в порт. WAIT <порт>,<маска И>,<маска XOR> - ждет ненулевого результата выражения INP(порт) AND <маска И> XOR <маска XOR> при разрешенных прерываниях. Глава 7. Прерывания. ---------- MSX-бейсик включает несколько групп прерываний: таймерное, от аппаратных средств, от клавиши CTRL/STOP и от ошибки. Для всех прерываний процедура использования одинакова: сначала нужно определить программу-обработчик оператором ON xxxx GOSUB, а затем разрешить прерывания оператором xxxx ON. Впоследствии можно запрещать прерывания оператором xxxx OFF или приостанавливать их xxxx STOP. ОN KEY GOSUB ,.... , KEY (#) ON|OFF|STOP Прерывание по нажатию функциональных клавиш. Когда клавиша связана с прерыванием, она лишается строковой интерпретации. ON STRIG GOSUB ,...,, STRIG(#) ON|OFF|STOP Прерывание происходит по нажатии кнопки пультов или пробела. ON INTERVAL= GOSUB - каждые таймерных тиков (1/ 60 сек.) происходит прерывание. ОN SPRITE GOSUB - происходит прерывание при обнаружении наложения спрайтов. ОN STOP GOSUB - вызывает прерывание по нажатию CTRL/STOP. При этом остановки программы не происходит. STOP OFF вообще отключает возможность остановки программы CTRL/STOP, STOP ON разрешает ее, но и прерывание тоже (если оно было установлено ранее.) ON ERROR GOTO ... - определяет программу обработки ошибок, возврат из этой программы осуществляется оператором RESUME. Формат файлов III-1 ------------------------------------------------------------ Часть III Руководство системного программиста. Глава 1. Формат входных и выходных файлов. -------------------------------- Входной текст представляет программу на языке бейсик в текстовом (ASCII) представлении с длиной строки до 254 символов. Строки могут нумероваться только при надобности, строки на которые нет ссылок, можно не нумеровать. Порядок следования номеров строк также произвольный, но не должно встречаться нескольких строк с одинаковым номером. Если строка оканчивается строковой константой, допустимо не ставить закрывающей кавычки, однако это рекомендуется делать. При чтении исходного текста повсюду в тексте, кроме строковых констант, буквы преобразуются в большие латинские. Разборка на операторы происходит построчно, при этом в качестве очередного оператора берется минимальная подстрока из очередной лексемы, где лексема-часть однородных А/Ц символов ограниченная каким-либо разделителем. Разделителями являются: конец строки, пробел, все специальные символы, а также при разборке числа - любой другой символ, не соответствующий набору возможных в данном числе символов. Оператор комментария должен быть последним или единственным в строке. Любой текст после комментария игнорируется. Выходной результат трансляции - файл на ассемблере Z80, состоящий из: заголовка, тела программы, дампа переменных и дампа строк. Дамп переменных обьявлен как DSEG, остальные части программы - как CSEG, что позволяет на этапе сборки выносить зону переменных в любое удобное место. Рассмотрим входной и выходной результаты трансляции на примере маленькой программы. Итак имеем на входе файл TEST со следующим содержимым: TEST.BAS------------------------------- pragma source A=1:B=A+1'this is remark print "A=";b --------------------------------------- Формат файлов III-2 ------------------------------------------------------------ Вызываем компилятор: 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 <- конец файла ---------------------------------------- Форматы данных III-3 ------------------------------------------------------------ Зона строковых констант является сегментом кода, что соответствует соглашению по MSX-ASCII-C 1.0. Так как рекомендованным сборщиком для бейсика является LINK, зона констант подклеивается к соответствующей программе, а зоны данных, т.е. переменные всех модулей выносятся в конец COM- файла. Работать с L80 не рекомендуется, так как он не инициализирует конструкции DS и поэтому может произойти накладка со строковыми переменными. Глава 2. Форматы данных на этапе исполнения. ---------------------------------- Программы используют три типа данных - целые, плавающие и строковые. Все операции с плавающими числами производятся с двойной точностью, поэтому одинарная точность - лишь способ хранения в памяти, но не тип данных. Данные представляются в следующих форматах: Целые: два байта, - стандартный способ хранения целых процессором Z80. Для представления отрицательных чисел используется дополнительный код. Плавающий тип: <характеристика><мантисса>, где мантисса - 3 или 7 байт для одинарной и двойной точности, содержащие упакованное BCD число из 6 или 14 цифр. Характеристика содержит: старший знаковый бит (если =1 - число отрицательное) и порядок, (десятичный -63 .. +63), сдвинутый на 64 ( 1 .. 127 ). Если байт характеристики нулевой, все число нулевое, Байт характеристики 80h не определен. При записи числа в переменную одинарной точности она округляется, при чтении дополняется справа четырьмя нулями. Строковый тип: Это самый сложный тип. Данные этого типа делятся на две части: дескриптор строки, хранящийся в теле строковой переменной и собственно тела строки, хранящегося где-нибудь в другом месте (в строковой куче, файловом буфере) или вообще отсутсвующего. Дескриптор строки имеет длину 3 байта и вид: DW <адрес тела строки> DB <длина строки> таким образом, максимальная длина строки составляет 255 байт. Если длина строки равна нулю, строка считается пустой, не имеет тела, и значение поля адреса тела строки игнорируется. Тело состоит из трех полей: DW <указатель на следующее тело> DW <указатель на дескриптор> <строка переменной длины> Файловые буфера III-4 ------------------------------------------------------------ В случае, когда переменная является переменной FIELD, т.е. тело находится в буфере файла и длина строки постоянна, два первых поля отсутствуют, но при этом указатель в дескрипторе указывает не на начало тела строки, а на четыре байта ниже. Данные целого и плавающего типа полностью совместимы с интерпретатором Бейсика, строковые данные на нижнем уровне - несовместимы. Поэтому следует внимательно транслировать программы с использованием самодельного доступа к телам строк и VARPTR. Впрочем, автор компилятора таких программ пока не встречал. Глава 3. Файловые буфера. --------------- Для оптимизации дискового ввода-вывода, а также для совместимости с MSX-интерпретатором в откомпилированной программе используется буферизованный ввод-вывод. При этом каждому каналу соответствует свой буфер с соответствующими системными зонами. Зоны эти таковы: 9 байт - FCB , совместимый с бейсиком; 256 байт - файловый буфер 38 байт - DOS FCB. Формат FCB для бейсика стандартен: +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, в конец его дописывается символ <ЕОF> (26h), и добавление в конец файла FOR APPEND осуществляется не с конца файла, а с момента первой встречи символа . Использование ресурсов III-5 ------------------------------------------------------------ Глава 4. Использование ресурсов. Компилятор и его библиотеки построены так, что легально используют все ресурсы MSX-компьютера. Возможно, это снижает производительность, но зато дает гарантию против конфликтов с различными системными программами. Для сокращения обьемов библиотек широко используется ROM BIOS и MSX-2 SUB-ROM. Известно, что вызовы SUB-ROM на компьютерах в некоторых конфигурациях вызывает сбои. Это происходит в частности на комплекте YIS 503-III + FD-051 из-за неправильно написанного дискового ПЗУ. Для ликвидации этого недоразумения в комплект поставки входит программа SLOT ( copyright Ф.Вагапов, 1989 ) для эмуляции нормального переключения слотов. Эту программу достаточно запустить один раз при начальной загрузке. SLOT - некоммерческая программа, она может быть беспрепятственно скопированна и использована для любых приложений. Все функции управления экраном, за исключением SET SCROLL, обращаются к ПЗУ компьютера и осуществляют интерфейс с аппаратурой строго соблюдая спецификации MSX. Режимы SCREEN 10,11,12 на MSX 2+ включаются также на аппаратном уровне. Глава 5. Оптимизация. ----------- Компилятор представляет собой однопроходный транслятор с локальной многофазной оптимизацией кода. По умолчанию оптимизатор включен на полное выполнение всех операций. Выходной ассемблер имеет команды Z-80, что позволяет в некоторых случаях даже без оптимизации получать более оптимальный код, нежели код от транслятора MSX-C. Оптимизатор отключаемый, локальный, единицей оптимизации является строка исходного текста. В связи с этим циклы, в особенности связанные с инициализацией или простыми векторными операциями, рекомендуется размещать на одной строке, что позволяет компилятору сильнее оптимизировать код программы. Оптимизация производится на уровне промежуточного кода и включает простую замену и замену с проверками, склеивание константных выражений и оптимизацию управляющих конструкций. Оптимизация гарантирует сжатие кода целочисленных и управляющих конструкций не менее чем 1.3 .. 2 раза по сравнению с неоптимизированным кодом. Неоптимизированный код по качеству соответствует коду ТУРБО-ПАСКАЛЯ или AZTEK-C и чрезвычайно медленный, из-за обилия стековых операций. Оптимизация III-6 ------------------------------------------------------------ В результате оптимизации НЕ ГАРАНТИРУЕТСЯ ПОРЯДОК ВЫЧИСЛЕНИЯ, поэтому , если требуется точный порядок вычислений, оптимизатор можно выключить. Кроме того, рекомендуется отключать оптимизатор при первой трансляции длинных программ, так как в таких программах наверняка найдутся ошибки, а без оптимизатора программа будет оттранслирована значительно (в 2 .. 3 раза) быстрее. Оптимизатор включается и выключается при помощи операторов PRAGMA и имеет 3 уровня оптимизации: - нет оптимизации - простая оптимизация ( PRAGMA OPTIMIZE:PRAGMA NOVECT ) - мощная оптимизация : реализуется по умолчанию, работают все алгоритмы оптимизации, происходит векторизация обращений к массивам. Поэтому, если нет нужды использовать уж очень оптимальную программу, или если у вас нет большого количества операций с массивами, этот режим можно отключить, так как векторизация требует длительного (относительно) времени. РЕЗУЛЬТАТ ТЕСТОВЫХ ПРОГОНОВ: При отключенном листинге и выводе исходного текста компилятор имеет следующие параметры: - при оптимизации: скорость в 1.5 .. 2.5 раза больше скорости MSX-C ; оптимальность кода на простых операциях лучше или равна, на сложных равна или несколько хуже оптимальности кода для MSX-C. - без оптимизации: скорость в 3 раза больше MSX-C, качество кода 1:1 соответствует коду порождаемому ТУРБО-ПАСКАЛЕМ (отличия состоят только в специфике ПАСКАЛЯ). Качество кода проверялось вручную, т.е. смотрелась возможность замены конструкций на более оптимальные по скорости и занимаемой памяти для небольшой циклической программы, содержащей основные операторы языка и работу над массивами в цикле. Касательно скорости компиляции следует заметить, что большие программы даже если и компилируются быстро, то линкуются чрезвычайно медленно. Так, программа в 530 строк на бейсике (правда чрезвычайно сложная и с большим количеством ввода-вывода и строковых операций) линковалась редактором LINK в течение 17 минут. СРАВНЕНИЕ С БЕЙСИКОМ. При прогоне програмы, в целых числах, с выводом на экран и строковыми операциями во вложенных циклах большой длительности компилятор показал скоростные характеристики 7:1 ... (9:1) без (при) оптимизации. При выполнении программы без вывода это соотношение намного больше (30:1..50:1). Раздельная компиляция III-7 ------------------------------------------------------------ Глава 6. Раздельная компиляция. --------------------- Средства поддержки раздельной компиляции обеспечивают создание модульных программ и подключение внешних модулей, написанных на C или ассемблере, а также секционирование программы внутри одного файла. Оператор PROCEDURE синтаксис: PROCEDURE Обявляет последующий код до конца файла либо до следующего оператора PROCEDURE подпрограммой с глобальным именем . Имя соответствует соглашению об именах МSX-C. Процедуры в одном файле разделяют все переменные, и не надо обьявлять их внешними или глобальными. Оператор GLOBAL синтаксис: GLOBAL [, ...] Определяет переменные ... глобальными. Оператор EXTERN синтаксис: EXTERN [, ...] Определяет переменные ... внешними. Они должны быть также обьявлены глобальными в другом модуле программы, но не в этом же файле. Оператор PRAGMA синтаксис: PRAGMA <параметр> <параметр>::={ OPTIMIZE,NOOPTIMIZE,LIST,NOLIST,SOURCE,VECT NOVECT,NOSOURCE,WORD_DATA,BYTE_DATA} Определяет режим работы компилятора: OPTIMIZE/NOOPTIMIZE - включает/выключает оптимизацию. LIST/NOLIST - включает/подавляет вывод листинга. SOURCE/NOSOURCE - включает/подавляет вывод листинга в комментарии ассемблерного текста. VECT/NOVECT - включают/подавляют векторизацию. BYTE_DATA - испольуются если в операторе DATA во всей WORD_DATA программе только числа : позволяет сэкономить память и ускорить выполнение. ПРИМЕЧАНИЕ: PRAGMA SOURCE вызывает вывод листинга и на экран. Устанавливаются по умолчанию: VECT,OPTIMIZE,NOLIST,NOSOURCE. Список функций П-1 ------------------------------------------------------------ Приложение А. Список функций, имеющихся в данной реализации Функции плавающей арифметики: SIN , COS , ATN , TAN , LOG , EXP , ABS , SQR , CDBL CSNG , RND , VAL Целочисленные функции: POS , STICK , STRIG , PAD , PDL , CVI , EOF , RND DSKF , POINT , LOC , LOF , FPOS , LEN , ASC , CSRLIN LPOS , INSTR , ABS , SGN , SQR , INP , PEEK , VPEEK VARPTR , INT , CINT , BASE , VDP , TIME , USR Функция USR при обращении к адресам менее 8000h переходит к ROM BIOS, иначе обращение идет к памяти ОЗУ. USR может принимать один целый аргумент через HL и так же возвращает результат. Функции ABS,SQR,RND описаны в II - 3.2.3. Строковые функции: LEFT$ , RIGHT$ , INKEY$ , CHR$ , INPUT$ , ATTR$ , DSKI$ STR$ , SPACE$ , MID$ , HEX$ , OCT$ , BIN$ , STRING$ Ошибки П-2 ------------------------------------------------------------ Приложение B. Наиболее вероятные причины ошибок. Ниже будут приведены основные причины возникновения пяти самых часто встречающихся ошибок. Syntax error - очень часто встречается, иногда второй ошибкой после какой-нибудь другой. В этом случае она исчезает по удалении первой ошибки. Кроме того часто встречается при трансляции бейсик-программ, из которых удалены все пробелы между операторов. Способ исправления - поставить где необходимо пробелы. Type mismatch - Чаще всего встетится при совпадении имен переменных разных типов (см. II - 1.3 , 3.1). Способ исправления - переименовать совпавшие переменные. Bad parametre - Следует проверить соответствие синтаксиса оператора стандарту. Может возникнуть при обьявлении массива с размерностью больше двух. Assignment to FIELD - Попытка присвоить значение полю FIELD при помощи обычного присвоения. Следует заменить его на LSET. Undefined array - при попытке использовать массив, обьявленный по умолчанию, что невозможно в данном компиляторе. Следует обьявить массив заранее. Комплект поставки П-3 ------------------------------------------------------------ Приложение C. Комплект поставки. В комплект поставки входят следующие файлы на диске: BAS.BAT - пакетный файл для нормальной компиляции; VBC.COM - компилятор бейсика; M80.COM - ассемблер; LINK.COM - редактор связей; SLOT.COM - программа для исправления ошибок SLOT CALL; BASIC.DOC - данное руководство; BK.REL - ядро компилятора; ILIB.REL - главная часть библиотеки; BASEND.REL - файл окончания; BITBLT.REL - файл подпрограмм BITBLT (его нужно употреблять, если в программе использованы операторы COPY) SAMPLE?.BAS - тексты демонстрационных программ.