\/d ГЛАВА VII. ДОПОЛНИТЕЛЬНЫЕ ВОЗМОЖНОСТИ ЯЗЫКА MSX-BASIC \/d- VII.1. РАБОТА С КЛАВИАТУРОЙ VII.1.1. Н е с т а н д а р т н ы й в в о д с к л а в и а т у р ы Как правило, ввод данных с клавиатуры пользователь осуществляет с помо- щью оператора INPUT. При этом нужно нажать как минимум две клавиши: одну для ввода символа и вторую для помещения его в память. При этом знак во- проса ("подсказка") и вводимый символ ("эхо") отображаются на экране. Строковая функция INKEY$ подавляет "подсказку" и "эхо" символа на экра- не и не требует нажатия клавиши ввода ("RETURN"). Функция ┌───────────────┐ │ INKEY$ │ , └───────────────┘ где INKEY ("KEY IN" - "вводить с клавиатуры") - служебное слово, в момент нажатия на какую-либо клавишу возвращает значение, равное вводи- мому по ней символу. Если клавиша не нажата, то значением функции INKEY$ является пустая строка (""). П р и м е р 1. ────────────── 10 W$=INKEY$:IF W$="" THEN 10 'Если клавиша не нажата, то компьютер пе- реходит к выполнению строки с номером 10. 20 PRINT W$:GOTO 10 'Вывод на экран символа, соответствующего нажатой клавише,и переход к выполнению строки 10. run a ◀── нажата клавиша "a" p │ r │ i │◀── нажата клавиша "F1" (для компьютера MSX-1) n │ t │ │ █ ◀── нажата клавиша "STOP" Break in 10 ◀── нажаты клавиши "CTRL"+"STOP" Ok При выполнении программы клавиатура постоянно опрашивается (сканирует- ся), и полученные коды записываются в область памяти, называемую б у ф е- р о м клавиатуры. Функция INKEY$, как Вы только что увидели, извлекает из буфера клавиатуры код набранного символа. Если буфер "пуст" (никакая клавиша не нажата!), то функция INKEY$ возвращает пустую строку. ┌──────────────────────────────────────────────────────────────────────┐ │ Важной особенностью функции INKEY$ является то, что она не выводит │ │ на экран символ, набранный на клавиатуре (если, конечно, в програм- │ │ ме отсутствует оператор PRINT !), и не "ожидает" ввода символа, ес- │ │ ли клавиша не нажата │ └──────────────────────────────────────────────────────────────────────┘ С помощью функции INKEY$ можно "прочитать" нажатие только тех клавиш, которым соответствует код какого-либо символа. Это делается так: IF INKEY$="с и м в о л" THEN ... Для обнаружения нажатия какой-либо из клавиш: ┌──────────────────────────────────────────────────────────────┐ │ "ESC", "TAB", "RETURN", "SELECT", "HOME/CLS", "INS","DEL", │ │ клавиши управления курсором, "CTRL+буква" │ └──────────────────────────────────────────────────────────────┘ используйте оператор: IF INKEY$=CHR$(K) THEN ... , где К - код клавиши, нажатия которой ожидается. К сожалению, клавиши ┌─────────────────────────────────────────────────────┐ │ "CAPS", "SHIFT", "GRAPH", "CTRL", "РУС", "STOP" │ └─────────────────────────────────────────────────────┘ "нечитаемы" операторами INPUT$ или INKEY$. Тем не менее для чтения этих клавиш достаточно прочесть буфер NEWKEY (11 байтов) по адресу &HFBE5 (см. раздел X.9.1). П р и м е р 2. Пример программы, останавливаемой нажатием клавиши ────────────── "SHIFT": 10 Z=PEEK(&HFBEB):IF Z<>254 THEN 10 П р и м е р 3. Вспомним, что функция ASC(α), где α - строковое выраже- ────────────── ние, возвращает десятичный код ASCII первого символа значения выражения α. Используя функцию INKEY$, можно получать десятичные коды ASCII "печатаемых" символов и некоторых управляющих клавиш. Интерес- ны результаты нажатия функциональных клавиш. 10 W$=INKEY$:IF W$="" THEN 10 ELSE PRINT ASC(W$):GOTO 10 run 27 ◀── нажата клавиша "ESC" 112 │ 112 ◀── нажата клавиша "p" 114 │ 114 ◀── нажата клавиша "r" 105 │ ◀── нажата клавиша "F1" 105 ◀── нажата клавиша "i" 110 │ 110 ◀── нажата клавиша "n" 116 │ 116 ◀── нажата клавиша "t" 32 │ 32 ◀── нажата клавиша "пробел" Break in 10◀── нажаты клавиши"CTRL" █ ◀── нажата клавиша "STOP" Ok +"STOP" 49 ◀── нажата клавиша "SHIFT"+"1" Таким образом, функциональные клавиши имеют ту особенность, что нажа- тие любой из них вызывает вывод кодов нескольких символов, составляющих ее текст. Приведем еще один пример применения функции INKEY$. 10 PRINT "Нажмите любую клавишу для продолжения" 20 IF INKEY$="" THEN 20 'Задержка до нажатия клавиши ┌────────────────┐ Функция │ INPUT$(n) │ └────────────────┘ служит для получения n последовательно вводимых с клавиатуры символов. Вводимые символы "накапливаются" в буфере клавиатуры без изображения их на экране дисплея. Когда ввод окончен (время ввода не ограничено!), то функция INPUT$() возвращает на экран дисплея строку введенных символов и курсор. ┌──────────────────────────────────────────────────────────────────┐ │ Запомните, что только нажатие клавиш "CTRL"+"STOP" прерывает │ │ действие данной функции! │ └──────────────────────────────────────────────────────────────────┘ П р и м е р 4. 10 W$=INPUT$(2):?W$:GOTO 10 ────────────── run █ █ ◀── нажата клавиша "a" ar ◀── нажата клавиша "r" █ Break in 10 ◀── нажаты клавиши "CTRL"+"STOP" Ok Этот оператор неудобно использовать для ввода д л и н н ы х символь- ных строк с клавиатуры, ибо Вы можете потерять контроль над вводом (вве- денные символы не видны на экране до тех пор, пока не введен последний из них). Однако можно использовать функцию INPUT$(1) для ввода с клавиатуры по одному символу (аналогично функции INKEY$). П р и м е р 5. ────────────── 1) 10 W$=INPUT$(1):?W$:GOTO10 2) 10 ? ASC(INPUT$(1)):GOTO 10 run run █ █ a ◀── нажата клавиша "a" 112 │ p ◀── нажата клавиша "p" 114 │ p │ 105 │◀── нажата клавиша "F1" r │ 110 │ на компьютере i │◀── нажата клавиша "F1" 116 │ серии MSX-1 n │ на компьютере 32 │ t │ серии MSX-1 █ │ 97 ◀── нажата клавиша "а" █ и так далее... █ и так далее... Таким образом, функцию INPUT$() можно также использовать для получения десятичных кодов ASCII символов, а также десятичных кодов ASCII некоторых управляющих и функциональных клавиш. П р и м е р 6. П а р о л ь ! ────────────── 40 CODE$="Секрет":COUNT=0:PRINT"Имя":INPUT N$ 70 PRINT "Пароль:" 110 P$=INPUT$(6) 'Чтение ш е с т и символов 120 IF P$=CODE$ THEN GOTO 150 130 COUNT=COUNT+1 140 IF COUNT<3 THEN GOTO 70 ELSE PRINT"Проход закрыт":END 150 PRINT:PRINT N$:PRINT"Проходи, приятель":END Результат работы программной строки 10 A$=INKEY$:IF A$="" THEN 10 может показаться эквивалентным результату работы команды A$=INPUT$(1) . Однако между ними есть различиe: нажатие клавиши "STOP" задерживает программу в цикле с оператором INKEY$, тогда как во время ожидания нажа- тия клавиши, "организованного" оператором INPUT$, клавиша "STOP" временно отключается. ┌───────────────────────────────────────────────────────────────────────┐ │ Это единственный способ временно отключить клавишу "STOP" в MSX-BASIC!│ └───────────────────────────────────────────────────────────────────────┘ VII.1.2. Ф у н к ц и о н а л ь н ы е к л а в и ш и При нажатии клавиши "F1" на дисплее компьютера серии MSX-1 появляется слово "print" (как если бы оно набиралось на клавиатуре посимвольно). Ана- логичным образом действует любая из остальных девяти функциональных кла- виш: "F2" , "F3" , "F4", "F5", "F6", "F7", "F8", "F9" , "F10",- генерируя на экране соответствующее слово. Подобные клавиши называются ф у н к ц и о н а л ь н ы м и (программируемыми), поскольку они не связа- ны жестко с каким-либо определенным символом. Генерируемые ими слова назы- ваются з н а ч е н и я м и функциональных клавиш. MSX-BASIC располагает средством, позволяющим изменять эти значения так, что при нажатии соответствующей клавиши генерируется заранее заданная це- почка символов. Этим средством является оператор ┌──────────────────┐ │ KEY n,T │ , └──────────────────┘ где: KEY ("key"-"клавиша") - служебное слово; n - арифметическое выражение, целая часть значения которого задает номер функциональной клавиши (n=1,2,...,9); T - символьное выражение. При выполнении данного оператора значение клавиши Fn становится равным значению символьного выражения T. Длина последнего не должна превышать 15. В противном случае будут использованы лишь первые 15 символов этого значе- ния. Отметим, что оператор KEY n,"" "сбрасывает" значение функциональной клавиши с номером n. Оператор ┌─────────────────┐ │ KEY LIST │ └─────────────────┘ выводит на экран дисплея значения 10 функциональных клавиш по порядку, по одной на дисплейную строку. Приведем ряд п р и м е р о в: 1) 10 KEY 1,CHR$(1)+CHR$(78) 2) 10 KEY 5,"print x;y" 20 KEY LIST run 3) 10 FOR S=1 TO 5:KEY S,"":NEXT: KEY 1, ♬ │ "GOSUB" auto │ для компью- 20 KEY S,"YES":KEY LIST goto │ теров серии ··· │ MSX-1 4) 10 X$="for x=1 to 15'заголовок":KEY5, _comterm │ X$:KEY LIST Ok 5) KEY 2,"LIST"+CHR$(13) 'При нажатии клавиши F2 в ы п о л н я е т с я команда LIST. Заметим, что символ CHR$(13) вызывает ввод команды (операто- ра), так же как и нажатие клавиши "RETURN"! Отметим, что при включении компьютера серии MSX-1 значения функциональ- ных клавиш устанавливаются по умолчанию следующим образом: print auto goto list run run"COM:" save"COM:" load"COM:" merge"COM:" _comterm Однако, если одновременно нажать на кнопку сброса " RESET " и клавишу DEL, то ключи будут установлены следующим образом: color auto goto list run color 15,4,4 cload" cont list. run Кстати,этого состояния функциональных клавиш можно достичь программным путем. Для этого используйте команды: DEFUSR=&H003E:X=USR(X) . При помощи функциональных клавиш можно значительно ускорить ввод про- грамм в память компьютера, если "занести в них" часто встречающиеся в про- грамме служебные слова. Использование функциональных клавиш очень полезно на этапе р е д а к- т и р о в а н и я программы. Каждая из клавиш может быть специально опре- делена для ускорения набора текста программы. Предположим, что Вы хотите ввести большое количество двоичных чисел. Это часто бывает необходимо при определении образа спрайта. Чтобы облег- чить себе работу, определите одну из функциональных клавиш так: KEY1,"DATA 00000000"+CHR$(13) , а затем введите команду AUTO. Нажмите клавишу "F1" несколько раз для полу- чения начальных "шаблонов" операторов DATA с последовательными номерами строк. Вам остается только отредактировать те строки, в которых необходи- мо заменить нули на единицы в нужных местах! VII.1.3 Д ж о й с т и к Человеческая изобретательность ни в чем не проявляется так, как в играх. Из письма Г.Лейбница Б.Паскалю В комплекте MSX-компьютера имеется два периферийных устройства для вво- да информации, которые называются д ж о й с т и к а м и ("joy stick" - "палочка радости"). Каждый джойстик состоит из двух блоков: р у к о я т к и и к н о п - к и . Обычно у джойстика имеется одна кнопка. Кроме того, к каждому джой- стику можно присоединить дополнительно еще по одной кнопке (отметим, что у некоторых моделей их две изначально!). Рукоятку джойстика можно перемещать вверх, вниз, направо, налево,а так- же в комбинациях: вверх+направо, вверх+налево, вниз+направо, вниз+налево. Таким образом, получается в о с е м ь допустимых направлений движения. ┌──────────────────────────────────────────────────────────────────┐ │ Важно отметить, что MSX-компьютер имеет встроенный "джойстик" │ │ (с номером 0). Роль р у к о я т к и этого "джойстика" игра- │ │ ют клавиши управления курсором, а роль к н о п к и играет │ │ клавиша "пробел"! │ └──────────────────────────────────────────────────────────────────┘ В MSX-BASIC имеется возможность нестандартного ввода информации при по- мощи джойстика. Делается это при помощи функций STICK(), STRIG(), PDL() и PAD(). Формат функции STICK() следующий: ┌───────────────┐ │ STICK(α) │ , └───────────────┘ где: STICK ("рукоятка")- служебное слово; α - арифметическое выражение, целая часть значения которого принад- лежит отрезку [0,2] и задает номер джойстика. 1 Эта функция возвращает целое число, принадлежащее 8 ▲ 2 отрезку [0,8] и отмечающее направление перемещения ру- \ │ / коятки джойстика, номер которого определяется значени- 7 ◀── 0 ──▶ 3 ем выражения α. Рисунок слева демонстрирует различные / │ \ значения функции STICK() (когда джойстик находится в 6 ▼ 4 нейтральном положении, функция возвращает значение 0). 5 Говорят, что функция STICK(0) "читает" клавиши управления курсором, функция STICK(1) "читает джойстик" в первом разъеме, функция STICK(2) "читает джойстик"во втором разъеме. Приведем возможные значения функции STICK(0): ▲ ▲ X=1, если нажата клавиша │; X=2, если нажаты одновременно клавиши ──▶ и │; X=3, если нажата клавиша ──▶;X=4,если нажаты одновременно клавиши ──▶ и │; X=5, если нажата клавиша │; ▼ ▼ X=6, если нажаты одновременно клавиши ◀── и │; X=7,если нажата клавиша◀──; ▲ ▼ X=8, если нажаты одновременно клавиши │ и ◀──; X=0, если не нажата ни одна из этих клавиш. Например, если Вы запустите программу 10 D=STICK(0):LOCATE 18,11:PRINT D:GOTO 10 и будете нажимать клавиши управления курсором, то будете получать значе- ния переменной D от 0 до 8. Если же у Вас есть джойстик, установите его в порт джойстика номер 1 (он находится на правой боковой панели компьютера), замените в строке 10 оператор D=STICK(0) на оператор D=STICK(1) и вновь запустите программу (итог будет аналогичным). Функция STRIG() определяет, нажата или нет нужная Вам к н о п к а . Формат функции STRIG() следующий: ┌─────────────┐ │ STRIG(β) │ , └─────────────┘ где: STRIG("Stick TRIGer"-"кнопка джойстика")- служебное слово: β - арифметическое выражение, целая часть которого принадлежит от- резку [0,4] и указывает на соответствующую кнопку джойстика. Функции STRIG(1) и STRIG(2) читают состояние кнопок джойстиков из ос- новного комплекта MSX. Функции STRIG(3) и STRIG(4) читают состояние допол- нительных кнопок джойстиков 1 и 2, причем: 1) функция STRIG(0) читает состояние клавиши "пробел"; 2) функция STRIG(1) читает состояние кнопки 1 джойстика в разъеме 1; 3) функция STRIG(2) читает состояние кнопки 1 джойстика в разъеме 2; 4) функция STRIG(3) читает состояние кнопки 2 джойстика в разъеме 1; 5) функция STRIG(4) читает состояние кнопки 2 джойстика в разъеме 2. Функция STRIG() возвращает значение либо ноль, если кнопка не нажата, либо -1 , если кнопка нажата. П р и м е р 1. IF STRIG(0) THEN BEEP ────────────── Оператор вызывает звуковой сигнал (BEEP), если кнопка джойстика нажата (т.е. STRIG(0) имеет значение -1). При использовании функции STRIG(0), например, в процессе компьютерной игры (скоростная стрельба по цели), она ежесекундно задействуется много раз. Для этих частых проверок значений существует специальный термин "оп- рос". Метод опроса иллюстрируется примером 2. Программа начинается с вопроса пользователю о том, располагает ли он джойстиком или работает за клавиату- рой. Далее запрашиваются состояния пусковых кнопок, и в зависимости от того, какая из них нажата, выбирается джойстик. П р и м е р 2 [76]. ─────────────────── 40 CLS:WIDTH 40 60 PRINT "Нажмите пусковую кнопку":PRINT "выбранного джойстика или" 80 PRINT "клавишу ПРОБЕЛ - для клавиатуры" 90 PRINT:PRINT:PRINT "Нажимайте":PRINT:PRINT 150 F=-1 160 FOR I=0 TO 4:IF STRIG(I) THEN F=I:NEXT I 190 IF F=-1 THEN GOTO 160 200 BEEP 240 IF F=0 THEN PRINT "Клавиатура "; 250 IF F=1 OR F=3 THEN PRINT "Джойстик А"; 260 IF F=2 OR F=4 THEN PRINT "Джойстик B"; 270 PRINT " в действии":END В ожидании нажатия клавиши "пробел" опрос будет выполняться постоянно, что делает возможной н е м е д л е н н у ю реакцию программы. Напомним Вам, что нажатие клавиши "пробел" может также проверяться с помощью функ- ции INKEY$, но в этом случае компьютер будет проверять текущее состояние буфера клавиатуры. З а м е ч а н и е. Функция STRIG(0) возвращает -1 только, если клави- ша "пробел" нажата во время в ы ч и с л е н и я значения этой функции. П р и м е р 3. 10 FOR I=0 TO 500:PRINT I:NEXT ────────────── 20 IF STRIG(0) THEN 10 ELSE 20 Обратите внимание, что если клавиша "пробел" нажата во время вывода ин- формации на экран, это событие не будет зафиксировано функцией STRIG(0), как произошло бы в случае замены программной строки 20 на строку 20 IF INKEY$=CHR$(32) THEN 10 ELSE 20 При применении функции STRIG(0) компьютер "реагирует" на нажатие клави- ши "пробел" т о л ь к о при выполнении 20 строки. Функция STRIG(0) не пе- рехватывает предварительного нажатия клавиши "пробел", тогда как функция INKEY$ реагирует на в с е предварительные нажатия. Сколько раз была на- жата клавиша "пробел", столько раз и выполнится соответствующая команда. П р и м е р 4. Ввод рисунков с клавиатуры при помощи "рукоятки" (кла- ────────────── виши управления курсором) и "кнопки" (клавиша "пробел") встроенного "джойстика" с номером 0. α) 10 CLS:X=16:Y=11 30 D=STICK(0) 40 IF D=1 OR D=2 OR D=8 THEN Y=Y-1 50 IF D=4 OR D=5 OR D=6 THEN Y=Y+1 60 IF D=2 OR D=3 OR D=4 THEN X=X+1 70 IF D=6 OR D=7 OR D=8 THEN X=X-1 80 IF X<0 THEN X=0 ELSE IF X>36 THEN X=36 90 IF Y<0 THEN Y=0 ELSE IF Y>20 THEN Y=20 95 LOCATE X,Y 100 IF STRIG(0) THEN PRINT "∗":GOTO 30 ELSE PRINT "+":GOTO 30 А теперь исправьте "∗" на " ". Что изменилось в работе программы? β) 10 COLOR 1,15:SCREEN 2 20 GOSUB 60:LINE (X,Y)-(X+10,Y+10) 30 X1=X:Y1=Y:A$=INKEY$:IF A$="n" OR A$="N" THEN ELSE 20 40 GOSUB 60:LINE (X1,Y1)-(X1+10,Y1+10),15:LINE (X,Y)-(X+10,Y+10) 50 X1=X:Y1=Y:A$=INKEY$:IF A$="r" OR A$="R" THEN 20 ELSE 40 60 D=STICK(0) 70 IF D=1 OR D=2 OR D=8 THEN Y=Y-1 80 IF D=4 OR D=5 OR D=6 THEN Y=Y+1 90 IF D=2 OR D=3 OR D=4 THEN X=X+1 100 IF D=6 OR D=7 OR D=8 THEN X=X-1 110 RETURN'──▶ П р и м е р 5. А теперь настала очередь "настоящего" джойстика! ────────────── α) 10 CLS:X=16:Y=11 30 D=STICK(1) 40 IF D=1 OR D=2 OR D=8 THEN Y=Y-1 50 IF D=4 OR D=5 OR D=6 THEN Y=Y+1 60 IF D=2 OR D=3 OR D=4 THEN X=X+1 70 IF D=6 OR D=7 OR D=8 THEN X=X-1 80 IF X<0 THEN X=0 ELSE IF X>36 THEN X=36 90 IF Y<0 THEN Y=0 ELSE IF Y>20 THEN Y=20 95 LOCATE X,Y 100 IF STRIG(1) THEN PRINT "∗":GOTO 30 ELSE PRINT "+":GOTO 30 β) 10 COLOR 1,15:SCREEN 2 20 GOSUB 60:LINE (X,Y)-(X+10,Y+10) 30 X1=X:Y1=Y:A$=INKEY$:IF A$="n" OR A$="N" THEN ELSE 20 40 GOSUB 60:LINE (X1,Y1)-(X1+10,Y1+10),15:LINE (X,Y)-(X+10,Y+10) 50 X1=X:Y1=Y:A$=INKEY$:IF A$="r" OR A$="R" THEN 20 ELSE 40 60 D=STICK(2) 70 IF D=1 OR D=2 OR D=8 THEN Y=Y-1 80 IF D=4 OR D=5 OR D=6 THEN Y=Y+1 90 IF D=2 OR D=3 OR D=4 THEN X=X+1 100 IF D=6 OR D=7 OR D=8 THEN X=X-1 110 RETURN'──▶ З а м е ч а н и е. С помощью регистров Программируемого Звукового Генератора (PSG) можно определить состояние джойстиков (состояние клавиш управления курсором с помощью регистров PSG определить нельзя!) и изменять состояние индикатора "РУС". Для Вас, конечно же, будет неожиданным сообщение о том, что PSG имеет 16 регистров, причем регистры с номерами 0÷13 отвечают за генерацию звука, а регистры 14 и 15 - за состояние джойстиков и индикатора "РУС". Для того, чтобы определить состояние джойстиков нужно в регистр с номе- ром 15 занести следующие значения: Д л я д ж о й с т и к а 1 Д л я д ж о й с т и к а 2 ┌───┬───┬───┬───┬───┬───┬───┬───┐ ┌───┬───┬───┬───┬───┬───┬───┬───┐ │ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 │ │ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 │ ├───┼───┼───┼───┼───┼───┼───┼───┤ ├───┼───┼───┼───┼───┼───┼───┼───┤ │ - │ 0 │ - │ 0 │ - │ - │ 1 │ 1 │ │ - │ 1 │ 0 │ - │ 1 │ 1 │ - │ - │ └───┴───┴───┴───┴───┴───┴───┴───┘ └───┴───┴───┴───┴───┴───┴───┴───┘ ...и прочитать регистр PSG с номером 14. Четыре его младших бита покажут состояние выбранного с помощью регистра 15 джойстика: ┌───┬───┬───┬───┬────┬────┬───┬───┐ │ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 │ ├───┤───┼───┼───┼────┼────┼───┼───┤ │ - │ - │ - │ - │ ─▶ │ ◀─ │ │ │ ▲ │ │ │ │ │ │ │ │ ▼ │ │ │ └───┴───┴───┴───┴────┴────┴───┴───┘ Если бит в данной позиции "сброшен",то джойстик направлен в показанном на таблице направлении. П р и м е р 6. Автор программы: Г.Беленький. 26.05.90. ───────────── 10 DATA 3E,0F :' LD A,0Fh ; В 15-й регистр PSG поместим 20 DАТА 1Е,03 :' LD Е,03h ; 3 (для джойстика 1) 30 DATA CD,93,00 :' CALL 0093h ; BIOS записи (оператор SOUND не 35 ' ; действует!) 40 DATA 3E,0E :' LD A,0Eh ; Читаем содержимое регистра 14 50 DATA CD,96,00 :' CALL 0096h ; BIOS чтения 60 DATA 32,00,E0 :' LD (E000h),A ; Полученное число поместим в 65 ' ; ячейку с адресом &HE000 70 DATA C9 :' RET 80 FOR I=0 TO 15:READ A$:POKE &HD000+I,VAL("&H"+A$):NEXT I 90 DEFUSR=&HD000 100 A=USR(0) ' Прочитаем состояние джойстика 1 110 PRINT RIGHT$("0"+BIN$(NOT(PEEK(&HE000) AND 15)),4) П р и м е р 7. Автор программы: Г.Беленький. 26.05.90. ───────────── 10 DATA 3E,0F :' LD A,0Fh ; Подпрограмма, позволяющая 20 DATA 1E,83 :' ld E,83h ; прочитать содержимое 30 DATA CD,93,00 :' CALL 0093h ; регистра PSG с номером 14, 40 DATA 3E,0E :' LD A,0Eh ; для определения 50 DATA CD,96,00 :' CALL 0096h ; состояния джойстика 1. 60 DATA 32,00,E0 :' LD (E000h),A ; 70 DATA C9 :' RET 80 FOR I=0 TO 15:READ A$:POKE &HD000+I,VAL("&h"+A$):NEXT I 90 DEFUSR=&HD000 100 SCREEN 2,0 110 SPRITE$(0)="ЧЧЧЧЧЧЧЧ" ' Образ спрайта 120 X=128:Y=96 ' Начальные координаты спрайта 140 PUT SPRITE 0,(X,Y),15,0 150 A=USR(0) ' Определяем состояние 160 A=PEEK(&HE000) AND 15 ' джойстика 1 170 IF A=10 OR A=14 OR A=6 THEN Y=Y-2 ' Изменение координат 180 IF A=9 OR A=13 OR A=5 THEN Y=Y+2 190 IF A=10 OR A=11 OR A=9 THEN X=X-2 200 IF A=6 OR A=7 OR A=5 THEN X=X+2 210 GOTO 140 Для того чтобы изменить состояние индикатора "РУС", нужно в регистре PSG с номером 15 изменить старший бит.Если этот бит равен 0, то индикатор включается, а если 1, то выключается. П р и м е р 8. Автор программы: Г.Беленький. 26.05.90. ───────────── 10 DATA 3E,0F :' LD A,0Fh 20 DATA 1E,00 :' LD E,00h 30 DATA CD,93,00 :' CALL 0093h 40 DATA C9 :' RET 50 FOR I=0 TO 7:READ A$:POKE &HD000+I,VAL("&H"+A$):NEXT I 60 DEFUSR=&HD000 70 A=USR(0) ' Включем индикатор "РУС" 80 FOR I=0 TO 50:NEXT I 90 POKE &HD003,128:A=USR(0) ' Выключем индикатор "РУС" 100 FOR I=0 TO 50:NEXT I 110 POKE &HD003,0:GOTO 70 Кроме только что рассмотренных функций STICK и STRIG для работы с джой- стиком можно использовать функции PDL и PAD. Формат функции PDL следующий: ┌────────┐ │ PDL(N) │ , └────────┘ где: PDL - служебное слово; N - арифметическое выражение, целая часть которого должна принад- лежать отрезку [1,12] (в противном случае последует сообщение об ошибке "Illegal function call" . Функция PDL(N) возвращает значение кода положения и г р о в о г о р ы- ч а ж к а, подключенного к разъему для джойстика. Для четных значений N считывается значение в разъеме 1, для нечетных - в разъеме 2. Если же у Вас нет игрового рычажка, но есть д ж о й с т и к , не огор- чайтесь и читайте дальше! Функция PDL(1) проверяет,происходило ли перемещение в п е р е д руко- ятки джойстика в разъеме 1, и возвращает 255 ("истина"), если рукоятка не перемещалась, или 0 ("ложь") - в противном случае. Функция PDL(2) проверяет, происходило ли перемещение в п е р е д руко- ятки джойстика в разъеме 2, и возвращает 255 ("истина"), если рукоятка не перемещалась, или 0 ("ложь") - в противном случае. Функция PDL(3) проверяет,происходило ли перемещение н а з а д рукоят- ки джойстика в разъеме 1, и возвращает 255 ("истина"), если рукоятка не перемещалась, или 0 ("ложь") - в противном случае. Функция PDL(4) проверяет,происходило ли перемещение н а з а д рукоят- ки джойстика в разъеме 2,и возвращает 255 ("истина"), если рукоятка не пе- ремещалась, или 0 ("ложь") - в противном случае. Функция PDL(5) проверяет,происходило ли перемещение в л е в о рукоят- ки джойстика в разъеме 1,и возвращает 255 ("истина"), если рукоятка не пе- ремещалась, или 0 ("ложь") - в противном случае. Функция PDL(6) проверяет,происходило ли перемещение в л е в о рукоят- ки джойстика в разъеме 2,и возвращает 255 ("истина"), если рукоятка не пе- ремещалась, или 0 ("ложь") - в противном случае. Функция PDL(7) проверяет,происходило ли перемещение в п р а в о руко- ятки джойстика в разъеме 1,и возвращает 255 ("истина"), если рукоятка не перемещалась, или 0 ("ложь") - в противном случае. Функция PDL(8) проверяет,происходило ли перемещение в п р а в о руко- ятки джойстика в разъеме 2,и возвращает 255 ("истина"), если рукоятка не перемещалась, или 0 ("ложь") - в противном случае. Функция PDL(9) проверяет, нажата ли кнопка 1 джойстика в разъеме 1, и возвращает 255 ("истина"), если кнопка не нажата, или 0 ("ложь") - в про- тивном случае. Функция PDL(10) проверяет, нажата ли кнопка 1 джойстика в разъеме 2, и возвращает 255 ("истина"), если кнопка не нажата, или 0 ("ложь") - в про- тивном случае. Функция PDL(11) проверяет, нажата ли кнопка 2 джойстика в разъеме 1, и возвращает 255 ("истина"), если кнопка не нажата, или 0 ("ложь") - в про- тивном случае. Функция PDL(12) проверяет, нажата ли кнопка 2 джойстика в разъеме 2, и возвращает 255 ("истина"), если кнопка не нажата, или 0 ("ложь") - в про- тивном случае. Основное назначение функции PAD - работа с графическим планшетом. Формат функции PAD следующий: ┌─────────┐ │ PAD(N) │ , └─────────┘ где: PAD ("pad"-"графический планшет") - служебное слово; N - арифметическое выражение, целая часть которого должна принад- лежать отрезку [0,7] (в противном случае последует сообщение об ошибке "Illegal function call"). Функция PAD(N) считывает данные с графического планшета, подключенного к разъему для джойстика. Значение разъема 1 считываются при N, равном 1,2 или 3 , а с разъема 2 при N, равном 4,5,6 или 7. Смысл возвращаемой величины для каждого значения N: 0 или 4 : возвращается 0 или -1 в зависимости от того, есть прикоснове- ние пера к планшету или нет; 1 или 5 : возвращается координата X точки касания; 2 или 6 : возвращается координата Y точки касания; 3 или 7 : возвращается состояние кнопки-переключателя (-1, если кнопка нажата, иначе 0). Однако функцию PAD() можно применять и в том случае, если у Вас нет графического планшета, но есть д ж о й с т и к. Функция PAD(0) проверяет, происходило ли перемещение в п е р е д ру- коятки джойстика в разъеме 1,и возвращает 0 ("ложь"), если рукоятка не пе- ремещалась, или -1 ("истина") - в противном случае. Функция PAD(3) проверяет, происходило ли перемещение в п р а в о ру- коятки джойстика в разъеме 1,и возвращает 0 ("ложь"), если рукоятка не пе- ремещалась, или -1 ("истина") - в противном случае. Функция PAD(4) проверяет, происходило ли перемещение в п е р е д ру- коятки джойстика в разъеме 2,и возвращает 0 ("ложь"), если рукоятка не пе- ремещалась, или -1 ("истина") - в противном случае. Функция PAD(7) проверяет, происходило ли перемещение в п р а в о ру- коятки джойстика в разъеме 2,и возвращает 0 ("ложь"), если рукоятка не пе- ремещалась, или -1 ("истина") - в противном случае. Функции PAD(1), PAD(2), PAD(5) и PAD(6) всегда возвращают значение 255. VII.2. П е р е х о д к п о д п р о г р а м м е по с о б ы т и ю Переход к подпрограмме по событию ( п р е р ы в а н и е в програм- ме пользователя) представляет собой особый тип условного перехода. Для выполнения "о б ы ч н о г о" условного перехода где-то в программе располагается оператор, проверяющий истинность условия и передающий управ- ление на указанный номер строки в соответствии с результатами проверки. Переход происходит только в том случае,если при выполнении программы в по- следовательности операторов был о б н а р у ж е н оператор перехода. Что же касается перехода к подпрограмме по с о б ы т и ю , то компью- тер непрерывно "проверяет" условие его возникновения в то время, как про- грамма пользователя выполняет другую работу. Обработка прерываний при наступлении события выполняется с помощью опе- раторов двух типов: ┌──────────────────────────────────────────────────────┐ │ ON с о б ы т и е GOSUB н о м е р с т р о к и │ (1) └──────────────────────────────────────────────────────┘ Этот оператор определяет событие, вызывающее проверку, а также место в программе, куда будет передано управление при наступлении события. ┌────────────────────────────────┐ │ с о б ы т и е ON/OFF/STOP │ (2) └────────────────────────────────┘ Если событие в к л ю ч е н о (ON) , то происходит переход, определен- ный оператором (1). Разумеется, что этот оператор должен быть предварите- льно выполнен. Если событие в ы к л ю ч е н о (OFF) (по умолчанию), то перехода на подпрограмму обработки не происходит. Если событие о с т а н о в л е н о (STOP), то переход при наступле- нии события не происходит, но информация о том, что событие произошло, за- поминается, а переход происходит только после обнаружения в программе опе- ратора с о б ы т и е ON . Отметим, что операторы (1) или (2) не выполняют "сами по себе" переход на подпрограмму обработки события. Когда выполнен оператор типа (1),относящийся к указанному событию, ком- пьютер начинает проверять,не произошло ли данное событие во время выполне- ния программы. Если событие произошло,текущий оператор все равно выполняется до конца. Затем компьютер проверяет, выполнен ли оператор типа (2). Возможны т р и варианта: α) оператор с о б ы т и е ON/OFF/STOP не был выполнен. Программа выполняется, как если бы событие не произошло; β) оператор с о б ы т и е ON был выполнен и является последним оператором этого типа, относящимся к данному событию. Происходит переход к подпрограмме, указанной в операторе ON с о б ы т и е GOSUB н о м е р с т р о к и При входе в эту подпрограмму неявно выполняется оператор с о б ы т и е STOP При выполнении оператора RETURN автоматически выполняется оператор с о б ы т и е ON , и управление передается оператору, следующему за тем, при выполнении кото- рого было обнаружено наступление события; γ) был выполнен оператор с о б ы т и е STOP , и он является последним оператором обработки данного события. Программа продолжает выполняться так, как будто бы событиe не произошло.Это событие запоминается, и если в дальнейшем в программе встречается оператор с о б ы т и е ON , относящийся к тому же событию, то происходит переход к подпрограмме обра- ботки события. Имеется возможность организовать переход на подпрограммы по соверше- нию таких событий, как истечение определенного интервала времени, нажатие какой-либо клавиши F1÷F10, нажатие клавиш "CTRL"+"STOP" и т.п. Об этом и пойдет речь в следующих разделах. ┌────────────────────────────────────────────────────────────────────────┐ │ Перед тем как выполнить программу, содержащую переход к подпрограммам │ │ по событию,не забудьте (если работаете на компьютере MSX-2) выполнить │ │ команду CALL NETEND . │ └────────────────────────────────────────────────────────────────────────┘ VII.2.1. П е р е х о д п о к л ю ч у Стоять я не могу... Мои колени слабеют... душно... Где ключи? Ключи, ключи мои... А.Пушкин Интерпретатор MSX-BASIC включает в себя средство, позволяющее использо- вать функциональные клавиши не только для ввода некоторого слова,но и для прерывания выполнения программы и вызова определенной подпрограммы. ┌────────────────────────────────┐ Оператор │ ON KEY GOSUB n1,n2,...,nk │ , └────────────────────────────────┘ где: ON ("по"), KEY ("ключ","клавиша"), GOSUB - служебные слова; n1,n2,...,nk - номера строк программы (1≤k≤10); осуществляет передачи управления подпрограммам, расположенным со строк n1, n2,...,nk, причем нажатие функциональной клавиши Fk (k=1,2,...,10) приво- дит к передаче управления подпрограмме, начинающейся со строки с номером nk (k=1,2,...,10). Если Вы хотите использовать только некоторые функциона- льные клавиши, то пропустите ненужные номера строк (оставив запятые!). Предварительно функциональную клавишу Fk необходимо "активизировать" оператором ┌──────────────────┐ │ KEY(k)ON │ . └──────────────────┘ Записанное в скобках значение k определяет,какая именно функциональная клавиша будет "активизирована". После выполнения приведенного выше опера- тора нажатие клавиши Fk не будет приводить к генерации какой-либо строки символов. Теперь перед выполнением каждого нового оператора программы интерпрета- тор будет проверять,не была ли нажата какая-нибудь "активизированная" фун- кциональная клавиша, и если такое нажатие произошло, то интерпретатор вы- зывает соответствующую подпрограмму. Для блокирования (запрещения) такого вызова необходимо выполнить опера- тор ┌──────────────────┐ │ KEY(k)OFF │ . └──────────────────┘ Как и в предыдущих случаях, значение в скобках k определяет номер функ- циональной клавиши, для которой выполняется данный оператор. Иногда возникает необходимость временно оградить программу от прерыва- ний, вызываемых функциональными клавишами, и в то же время запомнить каж- дое нажатие такой клавиши, с тем чтобы впоследствии можно было выполнить все соответствующие вызовы подпрограммы. Это достигается с помощью опера- тора ┌──────────────────┐ │ KEY(k)STOP │ , └──────────────────┘ который временно "дезактивизирует" функциональную клавишу Fk . Если после выполнения указанного выше оператора производились нажатия функциональной клавиши Fk, то все соответствующие вызовы подпрограмм все- таки будут реализованы, но не сразу, а только после выполнения оператора KEY(k)ON , вновь "активизирующего" эту клавишу. П р и м е р ы. ───────────── α) 10 ON KEY GOSUB 100 β) 10 ON KEY GOSUB 100 20 KEY(1)ON:SCREEN 2 20 KEY(1)ON:SCREEN 2 30 LINE(50,50)-(200,150),,B 30 LINE(50,50)-(200,150),,B 40 GOTO 30 40 GOTO 30 100 ' Подпрограмма 100 ' Подпрограмма 105 ::: 105 KEY(1)ON 110 BEEP:CLS 110 BEEP:CLS 120 FOR I=10 TO 90 STEP 10 120 FOR I=10 TO 90 STEP 10 130 CIRCLE(120,100),I:NEXT I 130 CIRCLE(120,100),I:NEXT I 140 CLS:RETURN 30 140 CLS:RETURN 30 γ) Наберите пример β), вставив строку: 135 IF I=50 THEN KEY(1)STOP . Оператор ON KEY GOSUB позволяет легко организовывать "листание" закон- ченных программных фрагментов во время выполнения программы; например, страницы справочной информации 1÷3 вызываются нажатием на клавиши "F1"÷"F3", демонстрационный пример выполняется при нажатии клавиши "F4", выход из программы - при нажатии клавиши "F5" и т.д. VII.2.2. П е р е х о д п о в р е м е н н о м у и н т е р в а л у ┌────────────────────────────┐ Оператор │ ON INTERVAL=α GOSUB n │ , └────────────────────────────┘ где: ON , INTERVAL ("интервал"), GOSUB- служебные слова; α - арифметическое выражение, целая часть значения которого принад- лежит отрезку [1,65535]; n - номер программной сроки, назначает интервалы времени, равные INT(α)/60 секунд, через которые компьютер периодически передает управление подпрограмме,рас- положенной с программной строки с номером n. Отсчет временных интервалов реализуется специальным счетчиком, принимающим значения 1,2,...,INT(α), 1,2,...,INT(α), 1,2,...,INT(α),... По аналогии с пунктом VII.2.1 счетчик "активизируется" оператором ┌─────────────────────┐ │ INTERVAL ON │ , └─────────────────────┘ "дезактивизируется" оператором ┌─────────────────────┐ │ INTERVAL OFF │ └─────────────────────┘ и временно "дезактивизируется" оператором ┌─────────────────────┐ │ INTERVAL STOP │ . └─────────────────────┘ П р и м е ч а н и е. Прежде чем запустить составленную Вами программу, убедитесь в том, что интервал INT(α)/60 не короче, чем время выполнения подпрограммы обработки, иначе она будет бесконечно вызывать саму себя,ибо в конце ее неявно выполняется оператор INTERVAL ON. П р и м е р 1. Проследите за выполнением следующего фрагмента при K=1, ────────────── 2,6. 10 INPUT K:ON INTERVAL=K*60 GOSUB 80 30 INTERVAL ON:GOSUB 100:INTERVAL STOP:GOSUB 100 50 INTERVAL ON:GOSUB 100:INTERVAL OFF:GOSUB 100 70 END 80 PRINT "Проверка":RETURN 100 FOR K=1 TO 7000:NEXT:RETURN П р и м е р 2. "Секундомер"! ────────────── 5 INPUT "Сколько секунд отсчитать";K:ON INTERVAL=60 GOSUB 80:S=1:PRINТ 0;TAB(4)"мин"0TAB(11)"сек":LOCATE POS(0),CSRLIN-1 10 INTERVAL ON:FOR I=1 TO K*1000/2.395:NEXT:LOCATE POS(0),CSRLIN+1:END 80 PRINT M;TAB(4) "мин";S;TAB(11) "сек":LOCATE POS(0),CSRLIN -1:S=S+1: IF S MOD 60=0 THEN J=0:LOCATE POS(0),CSRLIN:M=M+1:S=0 90 RETURN Обработка интервала оказывается очень удобной в игровых программах,где нужно повторять какое-либо действие через одинаковые интервалы времени. П р и м е р 3[76]. Данная программа позволяет наряду с вводом текста ────────────────── организовать отсчет времени ("часы") в правом верх- нем углу экрана. Заметим,что "опрос" клавиатуры выполняется с помощью фун- кции INKEY$. В этом случае функция INPUT$() неприменима,так как она ожида- ет нажатия клавиши, поэтому ввод с клавиатуры будет мешать нормальному из- менению состояния счетчика времени. 40 CLS:WIDTH 40:ON INTERVAL=50 GOSUB 230 60 TIME=0:INTERVAL ON 80 LOCATE 16,0,0:PRINT"Время:":LOCATE 24,0:PRINT H;":";M;":";S 100 INTERVAL ON 110 A$=INKEY$:IF A$=""THEN GOTO 110 ELSE PRINT A$; 140 'Очистка заполненного экрана 160 IF CSRLIN=23 AND POS(0)=37 THEN PRINT A$:CLS:LOCATE 0,1,0:GOTO 80 170 GOTO 110 190 'Подпрограмма обработки прерывания 230 X=POS(0):Y=CSRLIN 'Запоминание координат курсора 240 S=S+1 250 IF S=60 THEN M=M+1:S=0 260 IF M=60 THEN H=H-1:M=0 270 IF H=24 THEN H=0:LOCATE 24,0,0:PRINT 280 LOCATE 24,0,0:PRINT H;":";M;":";S:LOCATE X,Y,1:RETURN VII.2.3. П е р е х о д по н а ж а т и и к л а в и ш "CTRL"+"STOP" По оператору ┌──────────────────────┐ │ ON STOP GOSUB n │ , └──────────────────────┘ где: ON , STOP, GOSUB - служебные слова; n - номер программной строки; при нажатии на клавиши "CTRL"+"STOP" может осуществиться передача управ- ления подпрограмме, расположенной со строки n. При этом действие "CTRL"+"STOP" должно быть подтверждено (ON), отмене- но (OFF) или приостановлено (STOP) соответственно операторами: ┌─────────────────────────────────┐ │ STOP ON, STOP OFF, STOP STOP │ └─────────────────────────────────┘ П р и м е р. ─────────── 10 CLS:STOP ON:ON STOP GOSUB 80 20 PRINT"Нажмите клавишу RESET !!!":GOTO 20 80 PRINT"Вам уже ничего не поможет! Делайте, как подсказывают." 90 RETURN "На закуску" отметим интересный факт: 10 STOP ON:ON STOP GOSUB 50:FOR I=1 TO 5000:NEXT:END 50 POKE &HFBB0,1:RETURN '──▶ Нажатие клавиш "CTRL"+"STOP" игнорируется. "Доступ" к тексту программы становится возможным, если одновременно нажать пять клавиш: "CTRL"+"GRAPH"+"SHIFT"+"1"+"3" или четыре клавиши "CTRL"+"GRAPH"+"РУС"+"SHIFT" ! Если же оператор POKE &HFBB0,1 заменить на оператор POKE &HFBB0,0 , то Вас уже ничто не спасет! Обратите внимание,что обрабатывается только одновременное нажатие двух клавиш: "CTRL"+"STOP". Нажатие одной клавиши "STOP" просто "задержит" про- грамму. Средствами языка MSX-BASIC нажатие клавиши STOP "перехватываться" не может. Однако ее можно "отключить" во время выполнения функции INPUT$. Обработка нажатия клавиш "CTRL"+"STOP" позволит избежать любого вмеша- тельства в программу, выполняющуюся в Ваше отсутствие! VII.2.4. П е р е х о д п о д ж о й с т и к у Поговорим теперь об операторе перехода к подпрограмме по нажатию кноп- ки джойстика:┌────────────────────────────────────────────┐ │ ON STRIG GOSUB n[,n1][,n2][,n3][,n4] │ , └────────────────────────────────────────────┘ где: ON, STRIG, GOSUB - служебные слова; n - номер первой строки подпрограммы, которой передается управле- ние при нажатии клавиши "пробел" (кнопка "джойстика" с номером 0); n1 - номер первой строки подпрограммы, которой передается управле- ние при нажатии кнопки 1 джойстика 1; n2 - номер первой строки подпрограммы, которой передается управле- ние при нажатии кнопки 1 джойстика 2; n3 - номер первой строки подпрограммы, которой передается управле- ние при нажатии кнопки 2 джойстика 1; n4 - номер первой строки подпрограммы, которой передается управле- ние при нажатии кнопки 2 джойстика 2. Для того чтобы переход к подпрограмме по джойстику был возможен, его можно подтвердить, отменить или приостановить соответственно операторами ┌─────────────────────────────────────────────┐ │ STRIG(k)ON , STRIG(k)OFF , STRIG(k)STOP │ , └─────────────────────────────────────────────┘ где k - арифметическое выражение, целая часть значения которого определя- ет номер кнопки джойстика, INT(k)∈[0,4] (k=0 соответствует клавише "про- бел"). Оператор ON STRIG GOSUB приостанавливает нормальный ход выполнения про- граммы и передает управление соответствующей подпрограмме, если нажата со- ответствующая кнопка джойстика. Переход к первому номеру строки из списка осуществляется в том случае, если нажата клавиша "пробел", ко второму- ес- ли нажата кнопка 1 джойстика 1 и т.д. П р и м е р 1. ────────────── 5 STRIG(0) ON:STRIG(1) ON:STRIG(3) ON 7 ON STRIG GOSUB 100,200,,300 10 FOR I=1 TO 2000:NEXT:END 100 PRINT "Нажата клавиша 'ПРОБЕЛ'" :END 200 PRINT "Нажата кнопка 1 джойстика 1":END 300 PRINT "Нажата кнопка 2 джойстика 1":END П р и м е р 2[76]. Моделирование работы простого реле времени. ────────────────── 50 ON STRIG GOSUB 270 60 CLS:R=RND(-TIME):PRINT "Реле времени" 100 PRINT "Когда раздастся звонок, нажмите клавишу 'пробел'" 130 T=INT(RND(1)*500)+10 140 ON INTERVAL=T GOSUB 200 150 INTERVAL ON 160 GOTO 160 190 'Подпрограмма отсчета времени 200 INTERVAL OFF:BEEP:TIME=0:STRIG(0)ON 230 GOTO 230 260 'Анализ прерывания от джойстика 270 STRIG(0) OFF 280 PRINT "Ваша реакция":PRINT"=";TIME/60;"секунд":END Пока выполняется подпрограмма,всякий новый сигнал от кнопки джойстика откладывается до окончания текущей обработки. После возврата управления из подпрограммы интерпретатор определит нали- чие ожидающих сигналов,после чего будет выполнен очередной переход на под- программу обработки. ┌────────────────────┐ Оператор │ STRIG (k) ON │ └────────────────────┘ включает оператор ON STRIG GOSUB для соответствующего джойстика с номером k, после чего перед выполнением каждого оператора интерпретатор проверяет, нажата ли кнопка джойстика. ┌──────────────────┐ Оператор │ STRIG (k) STOP │ └──────────────────┘ приостанавливает разрешение обработки прерываний по нажатию кнопки джой- стика, но сохраняет информацию о нажатии. П р и м е р 3. Использование "встроенного" джойстика ! ────────────── 10 STRIG (0) ON:ON STRIG GOSUB 130:DEFINT A-Z 20 DATA 3,7,15,15,31,31,31,31,15,0,49,1,1,0,0,0,192,240,248,252,180,1 82,182,182,252,2,244,240,236,216,112,32 : '"Череп" 30 DATA 16,56,56,56,16,16,16,16 : 'Вид оружия 40 COLOR 15,1,1:SCREEN 2,2:X=125:Y=96 50 FOR T=1 TO 32:READA:B$=B$+CHR$(A):NEXT:SPRITE$(1)=B$:FOR I=1 TO 8:R EAD W:C$=C$+CHR$(W):NEXT:SPRITE$(2)=C$ 'Формирование спрайтов 60 GOSUB 70:GOTO 60 'Основная программа. 70 D=STICK(0):IF D=1 OR D=2 OR D=8 THEN Y=Y-3 'Движение "черепа" при 80 IF D=2 OR D=3 OR D=4 THEN X=X+3 'помощи клавиш управления 90 IF D=4 OR D=5 OR D=6 THEN Y=Y+3 'курсором 100 IF D=6 OR D=7 OR D=8 THEN X=X-3 110 IF Y<60 THEN Y=60 ELSE IF Y>145 THEN Y=145 ' Ограничение движения 120 PUT SPRITE 1,(X,Y):RETURN'──▶ 130 A=X:B=Y:C=A+8 'Подпрограмма полета стрелы 140 B=B-16:PUT SPRITE 2,(A,B),8,2:PUT SPRITE 3,(C,B),8,2:GOSUB 70 150 E=STRIG(0):IF B<10 THEN IF E=0 THEN RETURN ELSE 130 ELSE 140 П р и м е р 4. А теперь - использование "настоящего" джойстика ! ────────────── 10 STRIG (1) ON:ON STRIG GOSUB ,130:DEFINT A-Z 20 DATA 3,7,15,15,31,31,31,31,15,0,49,1,1,0,0,0,192,240,248,252,180,1 82,182,182,252,2,244,240,236,216,112,32 : '"Череп" 30 DATA 16,56,56,56,16,16,16,16 : 'Вид оружия 40 COLOR 15,1,1:SCREEN 2,2:X=125:Y=96 50 FOR T=1 TO 32:READA:B$=B$+CHR$(A):NEXT:SPRITE$(1)=B$:FOR I=1 TO 8:R EAD W:C$=C$+CHR$(W):NEXT:SPRITE$(2)=C$ 'Формирование спрайтов 60 GOSUB 70:GOTO 60 'Основная программа. 70 D=STICK(1):IF D=1 OR D=2 OR D=8 THEN Y=Y-3 'Движение "черепа" при 80 IF D=2 OR D=3 OR D=4 THEN X=X+3 'помощи клавиш управления 90 IF D=4 OR D=5 OR D=6 THEN Y=Y+3 'курсором 100 IF D=6 OR D=7 OR D=8 THEN X=X-3 110 IF Y<60 THEN Y=60 ELSE IF Y>145 THEN Y=145 ' Ограничение движения 120 PUT SPRITE 1,(X,Y):RETURN'──▶ 130 A=X:B=Y:C=A+8 'Подпрограмма полета стрелы 140 B=B-16:PUT SPRITE 2,(A,B),8,2:PUT SPRITE 3,(C,B),8,2:GOSUB 70 150 E=STRIG(1):IF B<10 THEN IF E=0 THEN RETURN ELSE 130 ELSE 140 VII.2.5. О д н о в р е м е н н а я о б р а б о т к а с о б ы т и й р а з л и ч н ы х т и п о в Обрадуем Вас: в одной программе допустима обработка нескольких событий различных типов! Однако для того, чтобы структура программы оставалась яс- ной, необходимо учитывать следующее: 1) перед входом в подпрограмму обработки события всегда неявно выполня- ется оператор с о б ы т и е STOP . Если в процессе выполнения этой подпрограммы происходит это же событие, то подпрограмма по завершении будет сразу же в ы з в а н а снова. Чтобы избежать этого, помещайте в начале подпрограммы оператор с о б ы т и е STOP или оператор с о б ы т и е OFF ; 2) применение операторов с о б ы т и е OFF и с о б ы т и е STOP "очищает" от обработки прерываний определенные участки Вашей программы; 3) если событие остановлено (STOP),то факт возникновения этого события запоминается. ┌────────────────────────────────────────────────────────────────┐ │ Если же событие того же типа возникает еще раз, то компьютер │ │ запоминает наступление только последнего события │ ; └────────────────────────────────────────────────────────────────┘ 4) приоритет (в порядке убывания) при одновременном возникновении собы- тий: α) обработка ошибок в программе пользователя; β) ON KEY GOSUB ; γ) ON STOP GOSUB ; δ) ON SPRITE GOSUB ; σ) ON STRIG GOSUB ; μ) ON INTERVAL GOSUB ; Φ) прерывания в локальной сети; Γ) другие прерывания. В заключение запомните, что использование в Вашей программе полдюжины (≈шесть!) операторов перехода к подпрограммам по событию может мгновенно завести в тупик любого, пытающегося разобраться в ней программиста! П р и м е р [76]. Предположим, что Вы управляете космическим кораблем, ──────────────── который может перемещаться вверх и вниз. Вы можете обстреливать появившийся вражеский корабль, который также стреляет по Ва- шему кораблю. Программа структурирована таким образом, что возможны лишь следующие столкновения спрайтов: α) вражеский корабль с Вашим снарядом; β) Ваш корабль с вражеским снарядом; γ) вражеский снаряд с Вашим снарядом. При попадании в цель вражеского снаряда Ваш корабль гибнет, и игра пре- кращается; если же Вам удается одним из своих снарядов поразить противни- ка - Ваш счет увеличивается. Игры такого типа безжалостно обнажают серьезную слабость языка BASIC: это весьма "м е д л е н н ы й" язык.Спрайты позволяют несколько увеличить скорость выполнения программы, но ясно,что без машинных кодов обойтись не удастся! 70 DEFINT A-Z:OPEN"GRP:"AS#1:DIM M(100):DIM T(7) 110 R=RND(-TIME) 120 ON STRIG GOSUB 1000 130 ON SPRITE GOSUB 1250 140 ON INTERVAL=10 GOSUB 1110 150 ON SPRITE GOSUB 1250 160 COLOR 15,1,1:SCREEN 2,0,0 190 'Начальная установка спрайтов 210 FOR I=0 TO 3 220 S$="" 230 FOR J=1 TO 8:READ S:S$=S$+CHR$(S):NEXT J 260 SPRITE$(I)=S$ 270 NEXT I 280 ' И з о б р а ж е н и е ф о н а 310 DRAW"bm0,176":DRAW"s4a0" 330 LINE(0,0)-(255,191),15,B:LINE(16,2)-(239,2),15 350 LINE(16,2)-(239,189),15,B:LINE(16,16)-(239,16),15 370 DRAW"bm136,5":COLOR 15 380 T$="Счет:":GOSUB 920 390 SC=0 400 PRINT#1,USING"######";SC 420 ' З в е з д н о е н е б о 440 FOR I=1 TO 100 450 E=INT(RND(1)*224)+16:F=INT(RND(1)*160)+16:PSET(E,F) 480 NEXT I 500 'Случайное движение корабля противника 530 FOR I=1 TO 100:M(I)=INT(RND(1)*130)+16:NEXT I 560 CIRCLE(160,60),40,11:PAINT(160,60),11 570 CIRCLE(175,45),10,9,,,13/10:PAINT(175,45),9 590 'У с т а н о в к а о т м е т о к 610 DRAW"bm10,4" 620 FOR I=10 TO 13:PUT SPRITE I,STEP(10,0),15,1:NEXT 650 X=24:Y=96:LI=14 660 F$="t180v12o2s11m100e16r16d#2" 670 M$="t180v12o6l24bgbgab" 680 W$="t180s1m3000o3c" 690 MX=200:MY=96:IX=IX+1:T=-2:F=0:J=0 700 STRIG(0)ON:SPRITE ON:INTERVAL ON 730 IF IX>100THEN IX=0 740 L=SGN(M(IX)-MY) 760 'О с н о в н о й ц и к л 780 PUT SPRITE 0,(X,Y),15,1 790 PUT SPRITE 1,(MX,MY),15,0 800 IF F THEN GOSUB 1040 810 IF J THEN GOSUB 1160 820 IF STICK(0)=1 THEN Y=Y-2 830 IF STICK(0)=5 THEN Y=Y+2 840 IF Y<=16 THEN Y=16 850 IF Y>=176 THEN Y=176 860 MY=MY+L:IF MY=M(IX)THEN IX=IX+1:GOTO 730 870 MX=MX-T:IF MX<40 OR MX>228 THEN T=-T 880 GOTO 780 890 'Подпрограмма вывода на экран 920 FOR I=1 TO LEN(T$):PRINT#1,T$:DRAW"bm-2,0":NEXT 960 RETURN 970 ' Свой с н а р я д 1000 IF F THEN RETURN 1010 PLAY"l8s8m300o6c","l8s8m300o7c" 1020 A=Y:B=X+16:F=1 1030 RETURN 1040 B=B+7 1050 IF B>232 THEN PUT SPRITE 3,(0,209):F=0:RETURN 1060 PUT SPRITE 3,(B,A),15,2:RETURN 1070 RETURN 1080 ' С н а р я д противника 1110 IF J THEN RETURN 1120 PLAY"l16s14m800o2a" 1130 BX=MX-8:BY=MY+4 1140 PUT SPRITE 4,(BX,BY),2,3 1150 J=-1:STRIG(0)ON:RETURN 1160 BX=BX-5 1170 IF BX<16 THEN BY=209:J=0 1180 PUT SPRITE 4,(BX,BY),2,3 1190 RETURN 1200 'Подпрограмма обработки прерываний. 1210 'Определение спрайтов по отношению к их расположению 1250 SPRITE OFF:INTERVAL OFF 1260 IF A+2>MY AND A+5<=MY+7 AND B+8>=MX THEN SI=30:PLAY M$:GOTO 1300 1270 IF BY+2>Y AND BY-7=BY AND A+5<=BY+7 AND BY+8>=36 THEN SI=10:PLAY W$:GOTO 1400 1290 SPRITE ON:INTERVAL ON:STRIG(0)ON:RETURN 1300 ' В с п ы ш к а на экране 1330 FOR I=0 TO 50 1340 COLOR,,RND(1)*16 1350 NEXT 1360 MY=96:MX=220 1370 ' Удаление снаряда 1400 PUT SPRITE 3,(0,209):F=0:A=0:B=209 1410 PUT SPRITE 4,(0,209):J=0:BX=0:BY=209 1420 IX=IX+1 1430 ' Увеличение счета 1460 DRAW"bm178,5":COLOR 1 1470 PRINT#1,USING"######";SC 1480 SC=SC+SI 1490 DRAW"bm178,5":COLOR 15 1500 PRINT#1,USING"######";SC 1510 COLOR,,1 1520 IF LI=9 THEN GOTO 1590 1530 PUT SPRITE LI,(0,209) 1540 SPRITE ON:INTERVAL ON 1550 RETURN 730 1560 ' К о н е ц и г р ы 1590 STRIG(0)OFF:INTERVAL OFF:SPRITE OFF 1600 PUT SPRITE 0,(0,209) 1610 PUT SPRITE 1,(0,209) 1620 PUT SPRITE 3,(0,209) 1630 PUT SPRITE 4,(0,209) 1640 LINE(24,60)-(232,76),15,BF 1650 DRAW"bm26,64":COLOR 1 1660 T$=" ИГРА ОКОНЧЕНА" 1670 GOSUB 920 1680 FOR I=1 TO 5000:NEXT 1690 S=STICK(0):IF S=0 THEN 1690 1700 IF S<>1 THEN 1720 1710 CLS:GOTO 310 1720 COLOR 15,4,4 1730 END 1740 ' Д а н н ы е для с п р а й т о в 1770 DATA 0, 60, 66,255, 66,255, 66, 60 1780 DATA 0,224, 68,255,255, 68,224, 0 1790 DATA 0, 64, 34, 63, 34, 64, 0, 0 1800 DATA 0, 2, 68,252, 68, 2, 0, 0 VII.3. И н и ц и а л и з а ц и я в MSX-BASIC При включении компьютера он приводится автоматически в некоторое исход- ное состояние (происходит его и н и ц и а л и з а ц и я) ; так, например, экран устанавливается в режим SCREEN 0 и окрашивается в определенный цвет. В языке MSX-BASIC для компьютеров MSX-2 существуют операторы для допол- нительной инициализации. Действие этих операторов в своем роде уникально: ┌─────────────────────────────────────────────────────────────────────┐ │ будучи о д и н раз выполненными, они воздействуют на компьютер │ │ при к а ж д о м включении (установленные ими значения запомина- │ │ ются в небольшой по объему памяти,сохраняющей свое содержимое при │ │ отключенном основном питании)! │ └─────────────────────────────────────────────────────────────────────┘ ┌──────────────────────┐ 1. Оператор │ SET ADJUST(X,Y) │ , └──────────────────────┘ где: SET ("установить"), ADJUST ("корректировка") - служебное слово; X и Y - арифметические выражения, целые части значений которых принадлежат отрезку [-7,8] (по умолчанию X=0,Y=0), регулирует положение используемой части экрана. ┌──────────────────────────────────────────┐ 2. Оператор │ SET BEEP [з в у к][,г р о м к о с т ь] │ , └──────────────────────────────────────────┘ где: SET , BEEP - служебные слова; з в у к - арифметическое выражение, целая часть значения которого принадлежит отрезку [1,4]; г р о м к о с т ь - арифметическое выражение,целая часть которого принадлежит отрезку [1,4]; устанавливает звук и громкость при выполнении оператора BEEP. Любой из параметров может быть опущен (его значение совпадет со значе- нием, установленным ранее), причем, если опущен первый параметр, то запя- тая должна быть сохранена. ┌─────────────────────────────────────────────┐ 3. Оператор │ SET TITLE ["з а г о л о в о к"][,ц в е т] │ , └─────────────────────────────────────────────┘ где: SET , TITLE ("заголовок") - служебные слова; з а г о л о в о к - значение строковой константы, длина которого не должна превышать 6 ; ц в е т - арифметическое выражение, целая часть значения которого принадлежит отрезку [1,4]; позволяет переопределять заголовок, возникающий на экране при включении компьютера. Если з а г о л о в о к имеет длину 6, то система будет "ожи- дать" нажатия любой клавиши после вывода заголовка на экран. ┌─────────────────────────────────┐ 4. Оператор │ SET PASSWORD "п а р о л ь" │ , └─────────────────────────────────┘ где: SET , PASSWORD - служебные слова; п а р о л ь - значение строковой константы, длина которого не дол- жна превышать 255 ; позволяет ввести пароль, проверяемый всякий раз при включении компьютера. Если Вы забыли пароль, нажмите клавиши "STOP" и "GRAPH" при включении. ┌──────────────────────────────────────┐ 5. Оператор │ SET PROMPT "п о д с к а з к а" │ , └──────────────────────────────────────┘ где: SET , PROMPT - служебные слова; п о д с к а з к а - значение строковой константы, длина которого не более 6 символов; позволяет переопределить стандартную системную подсказку Ok. П р и м е ч а н и е. Можно сохранить результат действия только одного из операторов SET TITLE, SET PASSWORD или SET PROMPT: использованный послед- ним "замещает" предыдущий. Пользуясь этой возможностью, можно отменить пароль, вернуться к исход- ному заголовку, к подсказке "Ok". Достаточно ввести команду SET PROMPT "Ok" ┌──────────────────────┐ 6. Оператор │ SET SCREEN │ , └──────────────────────┘ где: SET , SCREEN - служебные слова; позволяет с о х р а н и т ь значения параметров, относящихся к состоя- нию экрана, которые были ранее установлены операторами SCREEN, COLOR, KEY ON/OFF, WIDTH . Сохраняются только те параметры, которые могут вводиться в командном режиме: режим экрана (0 или 1); ширина экрана (от 1 до 80, если режим экрана =0; от 1 до 32, если режим экрана =1); цвет текста (от 0 до 15); цвет фона (от 0 до 15); цвет бордюра (от 0 до 15); высвечивание текста функциональных клавиш (ON или OFF); размер спрайтов (от 0 до 3); звук при нажатии клавиш (0 или 1); скорость передачи информации (1200 или 2400 бод); тип используемого принтера (MSX или другой тип); режим вывода (от 0 до 3). При включении компьютера неявно выполняются операторы SCREEN, COLOR, KEY ON/OFF и WIDTH, параметры которых были сохранены. Мартобря 86 числа. Н.Гоголь. Записки сумасшедшего ┌─────────────────────────────┐ 7. Оператор │ SET DATE "ММ/ДД/ГГ",[A] │ , └─────────────────────────────┘ где: SET , DATE ("дата") - служебные слова; ММ/ДД/ГГ - значение строковой константы, определяющей дату; A - необязательный параметр; определяет дату в формате: "ММ/ДД/ГГ" , где: ММ - месяц (от 00 до 12); ДД - день (от 00 до 31); ГГ - две последние цифры года. Отметим, что наличие нулей обязательно! Например: SET DATЕ "01/05/89" Если присутствует параметр A,то дата будет рассматриваться как д а т а подачи сигнала ("будильник с календарем") (при этом игнорируются месяц и год). ┌───────────────────────────┐ 8. Оператор │ SET TIME "ЧЧ:ММ:СС",[A] │ , └───────────────────────────┘ где: SET , TIME - служебные слова; ЧЧ:ММ:СС - значение строковой константы, определяющей время; A - необязательный параметр; задает время в следующем формате: "ЧЧ:ММ:СС" , где: ЧЧ - часы (от 00 до 23); ММ - минуты (от 00 до 59); СС - секунды (от 00 до 59). Отметим, что наличие нулей обязательно! Присутствие параметра A задает в р е м я подачи сигнала ("будильник"), причем секунды игнорируются. Учтите, что используя параметр А, всегда не- обходимо вводить вначале в р е м я , а лишь затем д а т у ! Все врут календари. А.Грибоедов. Горе от ума Для получения даты и времени MSX-BASIC предоставляет также еще два опе- ратора: ┌──────────────────────┐ 1) │ GET DATE Z$,[A] │ , └──────────────────────┘ где: GET ("получать"), DATE - служебные слова; Z$ - строковая переменная; A - необязательный параметр. Этот оператор присваивает значение даты переменной Z$ в формате "ММ/ДД/ГГ". Команда GET DATE Z$,A возвращает значение, определяющее дату подачи сигнала. ┌─────────────────────┐ 2) │ GET TIME Z$,[A] │ , └─────────────────────┘ где: GET, TIME - служебные слова; Z$ - строковая переменная; A - необязательный параметр. Этот оператор присваивает значение времени переменной Z$ в формате "ЧЧ:ММ:СС". Команда GET TIME Z$,A возвращает значение, определяющее время подачи сигнала. Отметим, что подача сигнала не является автоматической. Для ее осуществ- ления необходимо использовать подпрограмму, сравнивающую текущие дату и время с заданными параметром A и в случае совпадения выдающую сигнал BEEP или определенное сообщение. П р и м е р ы: ───────────── 1) set date "01/17/89" 2) set date "01/17/89",a Ok Ok get date d$:?d$ get date d$,a:?d$ 01/17/89 00/17/00 Ok Ok 3) set time "20:45:30" │ Начался отсчет 4) set time "20:45:30",a Ok │ времени Ok get time t$:?t$ get time t$,a:?t$ 20:45:40 ◀──── 10 с прошло с момента 20:45:00 Ok выполнения предыдущей Ok команды 5) set time "20:45:30":set time"20:50:30",a Ok get time t$:get time tm$,a:?t$,tm$ 20:45:43 20:50:00 Ok Более того: get time m$,a:?m$ ◀─── !!! 20:50:00 Ok 6) Ваш компьютер можно использовать и в бытовых целях. Если не хотите опаздывать на свидания, пользуйтесь возможностями компьютеров MSX-2 ! 10 SET BEEP 3,4 20 SET TIME "22:30:45":SET DATE "01/17/89" 30 SET TIME "22:31:45",A:SET DATE "01/17/89",A 40 GET TIME TM$,A:GET DATE DT$,A 50 GET TIME T$:GET DATE D$ 60 IF MID$(T$,1,6)+"00"=TM$ AND "00"+MID$(D$,3,4)+"00"=DT$ THEN BEEP:G OTO 50 ELSE GOTO 50 7) Если Вы хотите сохранить несколько версий программы,с которой Вы ра- ботаете, то Вас наверняка заинтересует следующий пример: 10 GET TIME Y$ 20 SAVE"A"+LEFT$(Y$,2)+MID$(Y$,4,2)+RIGHT$(Y$,2) 30 'Основная программа Запись программы в 14 ч 53 мин 33 с приведет к созданию файла с именем A145333. Записанные ранее версии Вашей программы остаются в непри- косновенности! VII.4. Р а б о т а с п р и н т е р о м Вначале напомним известные Вам факты. С помощью оператора PRINT можно "печатать" на э к р а н е дисплея текст в любом месте экрана (ему"активно помогает" в этом оператор LOCATE). При печати на б у м а г е оператора, аналогичного LOCATE, нет. Более того, при печати нельзя возвращаться в предыдущие строки (прогон бумаги осуществляется только в п е р е д). Возврат в начало текущей строки из ее конца в о з м о ж е н . Установка печатающей головки в заданное место строки производится с по- мощью так называемого т а б у л я т о р а - команды TAB (его использова- ние в "обычном" операторе PRINT, конечно же, Вам известно). П р и м е р 1. 10 FOR I=1 TO 50 ────────────── 20 LPRINT TAB(25-20*SIN(I/3));"Принтер!" 30 NEXT I Арифметическое выражение, задающее номер позиции печатающей головки, указывается после служебного слова TAB в скобках и значение его целой час- ти не должно превосходить 255. Использование в команде LPRINT специальных управляющих кодов и функции CHR$ позволяет управлять принтером, например, менять вид шрифта, его плот- ность и высоту. И наконец, ┌────────────────────────┐ │ 1 дюйм ≈ 2,54 см │ └────────────────────────┘ VII.4.1. К о м а н д ы д л я у п р а в л е н и я т и п о м п е ч а т и Эти команды используются для управления типом шрифта, шагом печати и "создания" специальных эффектов. VII.4.1.1. У п р а в л е н и е т и п о м ш р и ф т а Взгляните на следующую таблицу: ┌───────────────────────────────────────┬────────────────────────────┐ │ Ф у н к ц и я │У п р а в л я ю щ и й к о д│ ├───────────────────────────────────────┼────────────────────────────┤ │ Установка стандартных символов │ CHR$(27);"5" │ ├───────────────────────────────────────┼────────────────────────────┤ │ Установка наклонной печати ("италик") │ CHR$(27);"4" │ ├───────────────────────────────────────┼────────────────────────────┤ │ Печать графического символа MSX │ CHR$(1);CHR$(Код символа) │ └───────────────────────────────────────┴────────────────────────────┘ По умолчанию (при включении питания) осуществляется печать с т а н- д а р т н ы м и символами. Отметим, что первые два кода о т м е н я ю т друг друга. П р и м е р 2. ────────────── 10 LPRINT CHR$(27);"4":LPRINT "Данная строка напечатана италиком!" 20 LPRINT CHR$(27);"5":LPRINT "Эта строка напечатана стандартным шрифтом" Строка 10 включает тип шрифта "и т а л и к" с помощью кода CHR$(27);"4" , а строка 20 выключает его кодом CHR$(27);"5" . ┌────────────────────────────────────────────────────────────────────────┐ │ 4Буквы текста, напечатанного "и т а л и к о м", наклонены в п р а в о !5│ │ 4"Италик" может использоваться для выделения некоторых букв и слов.5 │ └────────────────────────────────────────────────────────────────────────┘ Заметим, что к а ж д ы й тип шрифта может комбинироваться с любым из трех шагов шрифта, а также с расширенной и выделенной печатью, о которых речь пойдет ниже. VII.4.1.2. У п р а в л е н и е ш а г о м ш р и ф т а Для печати используются три плотности шага: ц и ц е р о ( н о р м а л ь н а я ), э л и т е, у п л о т н е н н а я . Каждая из них может быть изменена с помощью команды расширения режима печати, при этом шаг увеличивается в два раза (см. раздел VII.4.1.3.). Предлагаем Вашему вниманию таблицу: ┌─────────────────────┬────────────┬─────────────────┐ │ Плотность шага │ Знаки/дюйм │ Управляющий код │ ├─────────────────────┼────────────┼─────────────────┤ │ Ц и ц е р о │ 10 │ CHR$(27);"P" │ ├─────────────────────┼────────────┼─────────────────┤ │ Ц и ц е р о │ 10 │ CHR$(27);"N" │ ├─────────────────────┼────────────┼─────────────────┤ │ Э л и т е │ 12 │ CHR$(27);"E" │ ├─────────────────────┼────────────┼─────────────────┤ │У п л о т н е н н а я│ 17 │ CHR$(27);"Q" │ └─────────────────────┴────────────┴─────────────────┘ Поговорим о шаге "ц и ц е р о". Команда, его устанавливающая, определя- ет максимальное число печатаемых колонок до 80 в печатающем устройстве де- сятидюймового типа (например, "Gemini-10XR") и до 136 - в печатающем уст- ройстве пятнадцатидюймового типа. При этом плотность шага устанавливается равной 10 знакам на дюйм в режиме печати текста и 160 точкам на дюйм в ре- жиме р а с т р о в о й (точечной) графики (о ней мы расскажем ниже). Немного об "э л и т е". Выбор этого шага устанавливает максимальное чи- сло печатаемых колонок до 96 в печатающем устройстве десятидюймового типа и до 163 в печатающем устройстве пятнадцатидюймового типа. В режиме рас- тровой печати плотность шага устанавливается равной 90 точкам на дюйм. Установка у п л о т н е н н о й печати приводит к тому,что вся после- дующая печать выполняется с плотностью 17 знакам на дюйм. Данная команда также устанавливает максимальное число печатаемых колонок на 136 в печата- ющем устройстве десятидюймового типа и на 233 в печатающем устройстве пят- надцатидюймового типа. П р и м е р 3. ────────────── 10 LPRINT CHR$(27);"N":LPRINT "WHAT IS YOUR NAME?" 30 LPRINT CHR$(27);"E":LPRINT "YOUR PRINTER PRINTS IN ELITE PITCH" 50 LPRINT CHR$(27);"Q":LPRINT "AS WELL AS CONDENSED, THE NARROOWEST PI TCH" 70 LPRINT CHR$(27);"Р" 80 LPRINT "PICA PITCH PRINTING IS PRINTER'S THIRD PITCH" run \/e- WHAT IS YOUR NAME? \/fe YOUR PRINTER PRINTS IN ELITE PITCH \/fc AS WELL AS CONDENSED, THE NARROOWEST PITCH \/fn PICA PITCH PRINTING IS PRINTER'S THIRD PITCH \/e Ok П р и м е р 4. ────────────── 10 LPRINT CHR$(27);"P":GOSUB 100 20 LPRINT CHR$(27);"E":GOSUB 100 30 LPRINT CHR$(27);"Q":GOSUB 100 40 LPRINT CHR$(27);"N":GOSUB 100:END 100 LPRINT "Я Вас любил...":RETURN run \/e- Я Вас любил... \/fe Я Вас любил... \/fc Я Вас любил... \/fn Я Вас любил... \/e Ok Различные типы плотности можно комбинировать с "италиком" и стандарт- ным шрифтом. VII.4.1.3. С п е ц и а л ь н ы е р е ж и м ы п е ч а т и ∗∗∗ M сказал молодому человеку, который не замечал,что его любит женщина:"Вы еще так юны, что, видно, разбираете только круп- ный шрифт". С.Шамфор. Характеры и анекдоты Коды для р а с ш и р е н н о й печати ┌─────────────────────────────────────┬─────────────────┐ │ Ф у н к ц и я │ Управляющий код │ ├─────────────────────────────────────┼─────────────────┤ │ Установка режима расширенной печати │ CHR$(14) │ ├─────────────────────────────────────┼─────────────────┤ │ Отмена режима расширенной печати │ CHR$(15) │ └─────────────────────────────────────┴─────────────────┘ Режим расширенной печати можно комбинировать с различной плотностью ша- га. При этом каждый символ будет напечатан в два раза шире, чем это предусмотрено выбором плотности шага. П р и м е р 5. ────────────── 10 LPRINT CHR$(14);"EXPANDED PICA PITCH" 20 LPRINT CHR$(27);"E":LPRINT "EXPANDED ELITE PITCH" 40 LPRINT CHR$(27);"Q":LPRINT "EXPANDED CONDENSED PITCH" 60 LPRINT CHR$(27);"P";CHR$(15) 70 LPRINT "NOW WE ARE BACK TO UNEXPANDED PICA PRINTING" run \/x EXPANDED PICA PITCH \/fe EXPANDED ELITE PITCH \/fc EXPANDED CONDENSED PITCH \/fn/x- NOW WE ARE BACK TO UNEXPANDED PICA PRINTING Ok Коды в ы д е л е н и я печати ┌────────────────────────────────┬──────────────────┐ │ Ф у н к ц и я │ Управляющий код │ ├────────────────────────────────┼──────────────────┤ │ Выбор печати двойным ударом │ CHR$(27);"G" │ ├────────────────────────────────┼──────────────────┤ │ Отмена печати двойным ударом │ CHR$(27);"H" │ ├────────────────────────────────┼──────────────────┤ │ Выбор выделенной печати │ CHR$(27);"!" │ ├────────────────────────────────┼──────────────────┤ │ Отмена выделенной печати │ CHR$(27);CHR$(34)│ └────────────────────────────────┴──────────────────┘ Выделить текст можно д в у м я способами: α) используя двойную печать со смещением вниз (печать двойным ударом); β) используя двойную печать со смещением вправо (выделенная печать). В обоих этих случаях символы пропечатываются д в а ж д ы. ┌───────────────────────────────────────────────────────────────────┐ │ Выделенную печать рекомендуется использовать с шагом "цицеро". │ │ Для другой плотности печати используйте печать д в о й н ы м │ │ ударом │ └───────────────────────────────────────────────────────────────────┘ Заметим, что отмена печати двойным ударом возвращает печатающее устрой- ство к предыдущему стилю печатания, а отмена выделенной печати возвращает печатающее устройство к стандартной печати. П р и м е р 6. ────────────── 10 LPRINT CHR$(14):GOSUB 100 'Расширенная печать включена 20 LPRINT CHR$(27);"4":GOSUB 100 '"Италик" включен 30 LPRINT CHR$(15):GOSUB 100 'Расширенная печать выключена 35 LPRINT CHR$(27);"5":GOSUB 100:END 100 LPRINT CHR$(27);"G":GOSUB 1000:LPRINT CHR$(27);"H" 110 LPRINT CHR$(27);"!":GOSUB 1000:LPRINT CHR$(27);CHR$(34) 120 END 1000 LPRINT "БУДЬТЕ СЧАСТЛИВЫ !!! Живите долго!":RETURN run \/x БУДЬТЕ СЧАСТЛИВЫ !!! Живите долго! \/i БУДЬТЕ СЧАСТЛИВЫ !!! Живите долго! \/x- БУДЬТЕ СЧАСТЛИВЫ !!! Живите долго! \/i-/fn БУДЬТЕ СЧАСТЛИВЫ !!! Живите долго! \/d БУДЬТЕ СЧАСТЛИВЫ !!! Живите долго! \/d-/e БУДЬТЕ СЧАСТЛИВЫ !!! Живите долго! Ok П р и м е р 7. ────────────── 10 LPRINT CHR$(27);"Q";"Миша";CHR$(27);"P";" + ";CHR$(27);"4";"Ирочка " ;CHR$(27);"5";"= ";CHR$(27);"!";"ЛЮБОВЬ !!!";CHR$(15);CHR$(27);"Q";" К араул";CHR$(27);CHR$(34) run QМишаP + 4Ирочка 5= !ЛЮБОВЬ !!!Q Караул" \/fn/e/i-/x- Ok Коды для о д н о н а п р а в л е н н о й печати ┌──────────────────────────────────┬────────────────────────────────────┐ │ Ф у н к ц и я │ У п р а в л я ю щ и й к о д │ ├──────────────────────────────────┼────────────────────────────────────┤ │ Выбор однонаправленной печати │ CHR$(27);">" │ ├──────────────────────────────────┼────────────────────────────────────┤ │ Отмена однонаправленной печати │ CHR$(27);"]" │ └──────────────────────────────────┴────────────────────────────────────┘ Однонаправленная печать используется в таблицах и схемах, так как обес- печивает с т р о г о вертикальное расположение символов и выравнивает печать вертикальных столбцов. После включения принтера устанавливается ре- жим двунаправленной печати, которая несколько быстрее однонаправленной. П р и м е р 8. ────────────── 20 FOR I=1 TO 10:LPRINT "++++++++++++++++++++":NEXT I 50 LPRINT:LPRINT:LPRINT CHR$(27);">" 70 FOR I=1 TO 10:LPRINT "++++++++++++++++++++":NEXT I Коды для п о д ч е р к и в а н и я ┌────────────────────────┬─────────────────┐ │ Ф у н к ц и я │ Управляющий код │ ├────────────────────────┼─────────────────┤ │ Выбор подчеркивания │ CHR$(27);"X" │ ├────────────────────────┼─────────────────┤ │ Отмена подчеркивания │ CHR$(27);"Y" │ └────────────────────────┴─────────────────┘ П р и м е р 9. ────────────── 10 LPRINT CHR$(27);"Q" 'Уплотненный шаг включен 20 LPRINT "Текст "; 30 LPRINT CHR$(14);"можно ";CHR$(15);"выделить"; 40 LPRINT CHR$(27);"X";" ПОДЧЕРКИВАНИЕМ";CHR$(27);"Y":END run QТекст можно выделитьX ПОДЧЕРКИВАНИЕМY \/fn/e/i-/x- Ok Использование кода ┌─────────────────┐ │ CHR$(27);"X" │ └─────────────────┘ приводит к автоматическому подчеркиванию в с е х последующих печатаемых символов (в том числе и пробелов). Отмена подчеркивания осуществляется командой: LPRINT CHR$(27);"Y" Коды печати в е р х н е г о и н и ж н е г о индексов ┌────────────────────────────────────┬─────────────────┐ │ Ф у н к ц и я │ Управляющий код │ ├────────────────────────────────────┼─────────────────┤ │ Выбор верхнего индекса │ CHR$(27);"s1" │ ├────────────────────────────────────┼─────────────────┤ │ Выбор нижнего индекса │ CHR$(27);"s2" │ ├────────────────────────────────────┼─────────────────┤ │ Отмена верхнего и нижнего индексов │ CHR$(27);"s0" │ └────────────────────────────────────┴─────────────────┘ Верхние и нижние индексы по высоте составляет половину с т р о ч н ы х символов. В е р х н и е индексы печатаются наравне с верхней частью обыч- ного символа, а н и ж н и е индексы - наравне с нижней частью обычного символа. Индексы часто применяются для ссылок, примечаний и в математичес- ких формулах. Пока печатающее устройство находится в режиме печати верхних или ниж- них индексов, обычная двунаправленная печать отменяется и заменяется од- нонаправленной. Более того, при печати верхних и нижних индексов устанав- ливается режим д в о й н о г о у д а р а . Выбор верхних и нижних индексов можно совмещать с выбором шрифта "ита- лик", однако индексы нельзя использовать с подчеркиванием и расширенной печатью. Заметим, что команда о т м е н ы верхних и нижних индексов отключает и направленную печать, и двойной удар. П р и м е р 10. ─────────────── 10 LPRINT "очень";CHR$(27);"s1";"полезная";CHR$(27);"s0";"ВОЗМОЖНОСТЬ"; CHR$(27);"s2";"ПРИНТЕРА";CHR$(27);"s0" run оченьs1 полезная s0ВОЗМОЖНОСТЬs2 ПРИНТЕРАs0 Ok VII.4.2. У п р а в л е н и е в е р т и к а л ь н о й п о з и ц и е й п е ч а т а ю щ е й г о л о в к и 1. И з м е н е н и е в ы с о т ы с т р о к и ┌───────────────────────────────────────┬──────────────────────────────┐ │ Ф у н к ц и я │ У п р а в л я ю щ и й к о д │ ├───────────────────────────────────────┼──────────────────────────────┤ │ Установка высоты строки на n/144 дюйма│ CHR$(27);"Т";"n1";"n2" │ ├───────────────────────────────────────┼──────────────────────────────┤ │ Установка высоты строки на 1/6 дюйма │ CHR$(27);"A" │ ├───────────────────────────────────────┼──────────────────────────────┤ │ Установка высоты строки на 1/8 дюйма │ CHR$(27);"В" │ │ │ (переключатель 1-2 выключен) │ ├───────────────────────────────────────┼──────────────────────────────┤ │ Установка высоты строки на 1/9 дюйма │ CHR$(27);"В" │ │ │ (переключатель 1-2 включен) │ └───────────────────────────────────────┴──────────────────────────────┘ При включении печатающего устройства плотность строк устанавливается равной 6 строкам в дюйме. Однако для данного печатающего устройства можно установить высоту строки на любое требуемое значение. Это делается командой: LPRINT CHR$(27);"T";"n1";"n2" , где n1 и n2 - цифры от 0 до 9, определяющие высоту строки в n/144 дюйма, величины n, n1 и n2 связаны при помощи формулы: ┌────────────┐ │ n=10·n1+n2 │ . └────────────┘ А теперь посмотрите, как легко и просто изменяется плотность строк. П р и м е р 11. ─────────────── 10 FOR I=48 TO 50 20 FOR J=48 TO 57 30 LPRINT CHR$(27);"T";CHR$(I);CHR$(J) 40 LPRINT "VARIABLE LINE SPACING WITH PRINTER" 50 NEXT J 60 NEXT I 70 LPRINT CHR$(27);"A" Приведем программу, "настраивающую" принтер на "очень мелкую" печать (она пригодится Вам для изготовления шпаргалок!) П р и м е р 12.┌────────────────────────────────────────────────────┐ ─────────────── │ 10 LPRINT CHR$(27);"T07";CHR$(27);"s1";CHR$(27);"Q"│ └────────────────────────────────────────────────────┘ Имеется и другой управляющий код для задания высоты строки. П р и м е р 13. ─────────────── 10 FOR I=1 TO 20 20 LPRINT CHR$(27);"B":LPRINT "LINE NUMBER";I 40 NEXT I В зависимости от положения двухпозиционного переключателя 1-2 (включен или выключен), который находится внутри принтера, задаются две различные высоты. Попробуйте! 2. У п р а в л е н и е п е р е в о д о м с т р о к ┌─────────────────────────────────────────┬─────────────────────────┐ │ Ф у н к ц и я │ Управляющий код │ ├─────────────────────────────────────────┼─────────────────────────┤ │ Возврат печатающей головки на левый край│ CHR$(13) │ ├─────────────────────────────────────────┼─────────────────────────┤ │ Перемещение бумаги вперед на одну строку│ CHR$(10) │ ├─────────────────────────────────────────┼─────────────────────────┤ │ Подача бумаги вперед на n строк │ CHR$(31);CHR$(n) │ ├─────────────────────────────────────────┼─────────────────────────┤ │ Подача бумаги на n строк без возврата │ CHR$(27);"a";CHR$(n) │ │ каретки │ │ └─────────────────────────────────────────┴─────────────────────────┘ Эти коды применяются для перемещения бумаги относительно печатающей го- ловки. Возврат печатающей головки в исходную позицию (возврат каретки) произ- водится командой ┌───────────────────────┐ │ LPRINT CHR$(13) │ . └───────────────────────┘ При этом бумага не продвигается. "Получив" код CHR$(10), печатающее устройство продвигает бумагу в п е- р е д на одну строку. Для перемещения печатающей головки на левый край с л е д у ю щ е й строки примените команду:┌──────────────────────────┐ │ LPRINT CHR$(13);CHR$(10) │. └──────────────────────────┘ П р и м е р 14. Сравните результаты работы командных строк: ─────────────── LPRINT "PROGRAM";CHR$(10);"BASIC" LPRINT "PROGRAM";CHR$(13);"BASIC" ┌───────────────────────────┐ Команда │ LPRINT CHR$(31);CHR$(n) │ , └───────────────────────────┘ где n - целое число (1≤n≤15), позволяет продвинуть бумагу в п е р е д на n строк. ┌──────────────────────────────┐ Команда │ LPRINT CHR$(27);"a";CHR$(n) │ , └──────────────────────────────┘ где n - целое число (1≤n≤255), перемещает бумагу на n строк (используя высоту текущей строки) без пере- мещения печатающей головки. Однако это не изменяет текущее значение верти- кального положения табуляции. Отметим, что данную команду можно записать и в таком виде: LPRINT CHR$(27);CHR$(97);CHR$(n) , где 97 - код символа "a". П р и м е р 15. ─────────────── 10 LPRINT "LINE NUMBER 1.":LPRINT "LINE NUMBER 2."; 30 LPRINT CHR$(27);"a";CHR$(3); 40 LPRINT "LINE NUMBER 3.":LPRINT "LINE NUMBER 4." Программная строка 30 позволяет переместить страницу вверх на 3 строки, печатающая головка при этом не перемещается. Следовательно, строка 40 пе- чатает сообщение начиная с колонки, в которой печатающая головка осталась в конце строки 20. 3. У п р а в л е н и е с т р а н и ц а м и ┌───────────────────────────────────────┬──────────────────────────────┐ │ Ф у н к ц и я │ У п р а в л я ю щ и й к о д │ ├───────────────────────────────────────┼──────────────────────────────┤ │ Перемещение бумаги на верхнюю часть │ CHR$(12) │ │ следующей страницы │ │ ├───────────────────────────────────────┼──────────────────────────────┤ │ Перемещение бумаги в позицию следующей│ │ │ вертикальной метки табуляции. │ │ │ Позиции вертикальной табуляции устана-│ CHR$(11) │ │ вливаются на строках с номерами, крат-│ │ │ ными 6 (6,12,18,...60) │ │ └───────────────────────────────────────┴──────────────────────────────┘ ┌────────────────────┐ Команда │ LPRINT CHR$(11) │ └────────────────────┘ приводит к перемещению печатающей головки в н и з в позицию следующей в е р т и к а л ь н о й метки табуляции или на верхнюю часть следующей страницы в порядке первоочередности нахождения. П р и м е р 16. Перед тем как запустить программу, следует выключить ─────────────── печатающее устройство и отрегулировать бумагу таким образом, чтобы лист был на одном уровне с верхом направляющей ленты на пе- чатающей головке, а затем включить печатающее устройство. 10 LPRINT "LINE NUMBER 1.":LPRINT "LINE NUMBER 2."; 30 LPRINT CHR$(12); 40 LPRINT "LINE NUMBER 3.":LPRINT "LINE NUMBER 4." 50 LPRINT CHR$(11); 60 LPRINT "LINE NUMBER 5.":LPRINT "LINE NUMBER 6." VII.4.3. У п р а в л е н и е г о р и з о н т а л ь н о й п о з и - ц и е й п е ч а т а ю щ е й г о л о в к и Как Вам известно, любой текст имеет правую и левую границу, называемые п о л я м и. 1. Поговорим об у с т а н о в к е п о л е й ┌──────────────────────────────────┬────────────────────────────────────┐ │ Ф у н к ц и я │ У п р а в л я ю щ и й к о д │ ├──────────────────────────────────┼────────────────────────────────────┤ │ Установка левого поля в колонке n│ CHR$(27);"L";"n1n2n3" │ ├──────────────────────────────────┼────────────────────────────────────┤ │Установка правого поля в колонке n│ CHR$(27);"/";"n1n2n3" │ └──────────────────────────────────┴────────────────────────────────────┘ Команда ┌──────────────────────────────────┐ │ LPRINT CHR$(27);"L";"n1n2n3" │ └──────────────────────────────────┘ устанавливает позицию н а ч а л а строки, определенную трехзначным чис- лом. Например, при выполнении команды LPRINT CHR$(27);"L";"126" л е в а я граница будет сдвинута на 126 символов. Команда ┌──────────────────────────────────┐ │ LPRINT CHR$(27);"/";"n1n2n3" │ └──────────────────────────────────┘ устанавливает позицию к о н ц а строки, определенную трехзначным числом. Например, при выполнении команды LPRINT CHR$(27);"/";"065" п р а в а я граница будет установлена на 65 символов. Для печатающего устройства д е с я т и д ю й м о в о г о типа (напри- мер, "Gemini-10XR") максимальная печатная позиция равна: α) для шага "ц и ц е р о" - 80, β) для шага "э л и т е" - 96, а γ) для у п л о т н е н н о г о шага - 136. Для печатающего устройства п я т н а д ц а т и д ю й м о в о г о типа максимальная печатная позиция равна: α) для шага "ц и ц е р о" - 136, β) для шага "э л и т е" - 163 и γ) для у п л о т н е н н о г о шага - 233. П р и м е р 17. Установка полей. ─────────────── 10 GOSUB 40 20 LPRINT CHR$(27);"L";"010";:LPRINT CHR$(27);"/";"070" 30 GOSUB 40:END 40 FOR I=1 TO 80:LPRINT "=";:NEXT I:RETURN Подпрограмма осуществляет печать 80 символов"="в одной строке. При пер- вом вызове подпрограммы все символы "=" печатаются в одной строке. Затем строка 20 устанавливает левое и правое поля. Теперь, после обращения к подпрограмме в строке 30, на одной строке уместятся лишь 60 символов, ос- тальные будут напечатаны со следующей строки. Для того, чтобы установить поля в исходное положение п о у м о л ч а- н и ю , имеются две возможности: α) Вы можете выключить и затем снова включить печатающее устройство; β) установить поля равными значениям по умолчанию. Это означает, что Вы должны установить левое поле на 0-й и правое поле на 80-й позиции на печа- тающем устройстве д е с я т и д ю й м о в о г о типа или 136 - на печа- тающем устройстве п я т н а д ц а т и д ю й м о в о г о типа. ┌─────────────────────────────────────────────────────────────────┐ │ Если изменять шаг печати после установки полей, поля не будут │ │ изменяться (количество символов в строке останется тем же)! │ └─────────────────────────────────────────────────────────────────┘ 2. У с т а н о в к а г о р и з о н т а л ь н ы х м е т о к ┌───────────────────────────────┬───────────────────────────────────────┐ │ Ф у н к ц и я │ У п р а в л я ю щ и й к о д │ ├───────────────────────────────┼───────────────────────────────────────┤ │ Перемещение на следующую гори-│ CHR$(9) │ │ зонтальную метку │ │ ├───────────────────────────────┼───────────────────────────────────────┤ │ Установка положений горизон- │CHR$(27);"(";"n11n12n13,...,nn1nn2nn3."│ │ тальных меток │ │ ├───────────────────────────────┼───────────────────────────────────────┤ │ Стирание установленных гори- │CHR$(27);")";"n11n12n13,...,nn1nn2nn3."│ │ зонтальных меток (селективное│ │ │ стирание меток) │ │ ├───────────────────────────────┼───────────────────────────────────────┤ │ Стирание всех горизонтальных │ CHR$(27);"2" │ │ меток │ │ └───────────────────────────────┴───────────────────────────────────────┘ Версия MSX-BASIC предоставляет возможность использования двух режимов работы с горизонтальными метками. Дело в том, что у компьютера и у принте- ра р а з н ы й набор меток. У компьютера метки располагаются строго через в о с е м ь позиций. У принтера же сразу после его включения горизонтальные метки автоматически устанавливаются через д е с я т ь печатных позиций. Кроме того, набор меток печатающего устройства можно изменять программным путем. Информация о том, из какого набора будут взяты горизонтальные метки та- буляции, хранится в ячейке памяти с адресом &HF418. Если содержимое этой ячейки равно нулю, то принтер будет работать с метками из набора компьюте- ра. Если же содержимое ячейки памяти отлично от нуля,то печатающее устрой- ство будет работать с горизонтальными метками из своего набора. Для перемещения печатающей головки в позицию следующей горизонтальной метки табуляции применяется команда ┌──────────────────┐ │ LPRINT CHR$(9); │ . └──────────────────┘ П р и м е р 18. Демонстрация использования горизонтальных меток. ─────────────── α) 10 LPRINT "ONE";CHR$(9);"TWO";CHR$(9);"THREE";CHR$(9);"FOUR" run ONE TWO THREE FOUR ▲ ▲ ▲ │ │ │ 8-я позиция 16-я позиция 24-я позиция Ok β) POKE &HF418,1 Ok 10 LPRINT "ONE";CHR$(9);"TWO";CHR$(9);"THREE";CHR$(9);"FOUR" run ONE TWO THREE FOUR ▲ ▲ ▲ │ │ │ 10-я позиция 20-я позиция 30-я позиция Ok γ) Установка позиции горизонтальной табуляции (установка положений ме- ток) осуществляется следующей командой: ┌───────────────────────────────────────────────────────────┐ │ LPRINT CHR$(27);"(";"n11n12n13,n21n22n23,...nn1nn2nn3." │ . └───────────────────────────────────────────────────────────┘ При этом аннулируются все позиции текущей горизонтальной табуляции и уста- навливаются новые, определенные трехзначными числами. POKE &HF418,1 Ok 10 LPRINT CHR$(27);"(";"008,016,024." 20 LPRINT "ONE";CHR$(9);"TWO";CHR$(9);"THREE";CHR$(9);"FOUR" run ONE TWO THREE FOUR ▲ ▲ ▲ │ │ │ 8-я позиция 16-я позиция 24-я позиция Ok Метки будут установлены в колонках 8, 16 и 24. Запятые в 10-Й строке используются для разделения цепочки меток, точка - для окончания определе- ния. δ) Для того чтобы стереть часть горизонтальных меток из набора печата- ющего устройства, существует следующая команда: ┌───────────────────────────────────────────────────────────┐ │ LPRINT CHR$(27);")";"n11n12n13,n21n22n23,...nn1nn2nn3." │ . └───────────────────────────────────────────────────────────┘ По коду селективного стирания табуляции стираются позиции табуляции, определенной трехзначными номерами. POKE &HF418,1 Ok 10 LPRINT CHR$(27);"(";"008,016,024." 20 LPRINT "ONE";CHR$(9);"TWO";CHR$(9);"THREE";CHR$(9);"FOUR" 30 LPRINT CHR$(27);")";"016." 40 LPRINT "ONE";CHR$(9);"TWO";CHR$(9);"FOUR" run ONE TWO THREE FOUR ONE TWO FOUR Ok В настоящей программе метки стираются в колонке 16. ┌───────────────────────┐ Если командой │ LPRINT CHR$(27);"2" │ Вы уберете все метки, то при └───────────────────────┘ использовании меток из набора принтера команда LPRINT CHR$(9) будет игно- рироваться. 3. П р о ч и е к о м а н д ы д л я у п р а в л е н и я г о р и з о н т а л ь н о й п о з и ц и е й п е ч а т а ю щ е й г о л о в к и ┌───────────────────────────────┬───────────────────────────────────────┐ │ Перемещение на n пробелов │ CHR$(27);"b";CHR$(n) │ ├───────────────────────────────┼───────────────────────────────────────┤ │ Перемещение на n точек │ CHR$(27);"F";"n1n2n3n4" │ ├───────────────────────────────┼───────────────────────────────────────┤ │ Смещение на один символ влево │ CHR$(8) │ └───────────────────────────────┴───────────────────────────────────────┘ ┌───────────────────────────────┐ Команда │ LPRINT CHR$(27);"b";CHR$(n) │ , └───────────────────────────────┘ где n - целое число из отрезка [1,255], позволяет пропустить n печатных позиций. Эта команда не изменяет текущего значения позиции горизонтальной табуляции. ┌─────────────────────────────────┐ Команда │ LPRINT CHR$(27);"F";"n1n2n3n4" │ , └─────────────────────────────────┘ где n1,n2,n3,n4 - цифры от 0 до 9, перемещает печатающую головку на n то- чечных позиций в п р а в о. При этом величина n должна принадлежать от- резку [0,479] и вычисляется по следующей формуле: ┌──────────────────────────────┐ │ n = 1000·n1+100·n2+10·n3+n4 │ . └──────────────────────────────┘ ┌─────────────────────┐ Команда │ LPRINT CHR$(8) │ └─────────────────────┘ смещает печатающую головку на одну колонку в л е в о . Если печатная го- ловка находится в исходной позиции, то команда игнорируется. Эта команда используется для печати дополнительных знаков. VII.4.4. К о м а н д ы у п р а в л е н и я г р а ф и к о й Принтер можно использовать в качестве г р а ф о п о с т р о и т е л я, т.е. устройства, которое позволяет вывести на печать рисунки, графики и т.д. Дело в том, что принтер печатает восемью штырьками печатающей голов- ки. Каждый штырек печатает о д н у точку. Существует р е ж и м р а с - т р о в о й г р а ф и к и , позволяющий непосредственно управлять уда- ром к а ж д о г о штырька. Взгляните на следующую таблицу: ┌───────────────────────────────┬─────────────────────────────────────┐ │ Ф у н к ц и я │ У п р а в л я ю щ и й к о д │ ├───────────────────────────────┼─────────────────────────────────────┤ │ Печать растровой графики │ CHR$(27);"S";"n1n2n3n4" │ ├───────────────────────────────┼─────────────────────────────────────┤ │ Повторение растровой графики │ CHR$(27);"V";"n1n2n3n4";CHR$(m) │ └───────────────────────────────┴─────────────────────────────────────┘ Режим р а с т р о в о й графики устанавливается командой ┌──────────────────────────────────┐ │ LPRINT CHR$(27);"S";"n1n2n3n4"; │ , └──────────────────────────────────┘ где n1,n2,n3,n4 - цифры от 0 до 9. Если обозначить n - количество положений печатающей головки в строке при растровой печати, то n=1000·n1+100·n2+10·n3+n4 . На к а ж д о е такое положение нужно подать команду ┌───────────────────────────────────────────────┐ │ LPRINT CHR$(Двоичный код положения штырька); │ └───────────────────────────────────────────────┘ с указанием того, какие штырьки печатающей головки должны печатать. - Боюсь, что от объяснений все проигрывает,- сказал он. - Одни только результаты впечатляют гораздо больше. П р и м е р 19. А.Конан Дойль. Приключения клерка ─────────────── К о д ш т ы р ь к а &b00000001 ───▶ · &b00000010 ───▶ · · &b00000100 ───▶ · · · &b00001000 ───▶ · · · · &b00010000 ───▶ · · · · &b00100000 ───▶ · · · &b01000000 ───▶ · · &b10000000 ───▶ · ▲ ▲ ▲ ▲ │ │ │ │ &b11111111 &b01111110 &b00111100 &b00011000 10 LPRINT CHR$(27);"S";"0008"; 20 FOR T=1 TO 2:LPRINT CHR$(&B11111111);:NEXT 30 FOR T=1 TO 2:LPRINT CHR$(&B01111110);:NEXT 40 FOR T=1 TO 2:LPRINT CHR$(&B00111100);:NEXT 50 FOR T=1 TO 2:LPRINT CHR$(&B00011000);:NEXT run ·· ···· ······ ········ ········ ······ ···· ·· Ok П р и м е р 20. Программа печатает прямоугольник размерами ─────────────── 200 точек ╳ 16 точек . 10 DATA &B00000001,&B10000000 30 LPRINT CHR$(27);"T16"; 'Команда устранения пробелов между строками 40 FOR I=1 TO 2 50 LPRINT CHR$(27);"S0200";:LPRINT CHR$(255);:READ A 80 LPRINT STRING$(198,CHR$(A));:LPRINT CHR$(255) 100 NEXT I Сделаешь раз по сто - вот и будет просто. П.Федотов ┌───────────────────────────────────────────┐ Команда │ LPRINT CHR$(27);"V";"n1n2n3n4";CHR$(m) │, └───────────────────────────────────────────┘ где n1,n2,n3,n4 - цифры от 0 до 9; m - целое число, принадлежащее отрезку [0,255]; позволяет повторить N раз изображение вертикальной линии (8 точек),шаблон которой устанавливается двоичным представлением числа m. Величина N определяется по формуле: N=1000·n1+100·n2+10·n3+n4 Отметим, что для выполнения этой команды н е требуется предваритель- ной установки растровой печати. П р и м е р 21. Результат действия следующих двух фрагментов одинаков! ─────────────── α) 10 LPRINT CHR$(27);"S";"0008"; 20 FOR T=1 TO 8:LPRINT CHR$(&B11111111);:NEXT β) 10 LPRINT CHR$(27);"V";"0008";CHR$(&B11111111) VII.4.5. И с п о л ь з о в а н и е м а к р о к о м а н д ┌───────────────────────────────┬─────────────────────────────────────┐ │ Ф у н к ц и я │ У п р а в л я ю щ и й к о д │ ├───────────────────────────────┼─────────────────────────────────────┤ │ Определение макрокоманды │ CHR$(27);"+";...;CHR$(0) │ │ (макроопределение) │ ▲ │ │ │ │ │ │ │ Совокупность команд │ ├───────────────────────────────┼─────────────────────────────────────┤ │ Выполнение макрокоманды │ CHR$(27);"%" │ └───────────────────────────────┴─────────────────────────────────────┘ Команда ┌──────────────────────────────────┐ │ LPRINT CHR$(27);"+";...;CHR$(0) │ └──────────────────────────────────┘ отменяет существующую макрокоманду и заменяет ее определяемой макрокоман- дой. Максимальное число символов в макрокоманде (не считая символов "+" и CHR$(0)) равно 16, в противном случае печатающее устройство будет реагиро- вать только на первые 16 символов макроопределения. ┌──────────────────────────┐ Команда │ LPRINT CHR$(27);"%" │ └──────────────────────────┘ выполняет макрокоманду, которая предварительно была определена при помощи макроопределения. После описания макроопределения Вы можете использовать макрокоманду в любой требуемый момент времени,и печатающее устройство будет "делать" все, что Вы включили в макроопределение. П р и м е р 22. Макроопределение для установки принтера в исходное ─────────────── положение всех стилей печати. 10 LPRINT CHR$(27);"+"; ' Начало макроопределения 20 LPRINT CHR$(27);"P"; ' Шаг "цицеро" 30 LPRINT CHR$(15); ' Отмена расширенной печати 40 LPRINT CHR$(27);"H"; ' Отмена двойного удара 50 LPRINT CHR$(27);CHR$(34); ' Отмена выделенной печати 70 LPRINT CHR$(27);"s";"0"; ' Отмена индексов 80 LPRINT CHR$(27);"5"; ' Отмена шрифта "италик" 90 LPRINT CHR$(27);"Y"; ' Отмена подчеркивания 100 LPRINT CHR$(27);"A" ' Высота строки =24/144 дюйма 110 LPRINT CHR$(0) ' Конец макроопределения Печатающее устройство будет "помнить" об этом макроопределении до тех пор, пока не будет введено новое макроопределение! Теперь посмотрите, как можно использовать описанное макроопределение. П р и м е р 23. Программа печатает всего одну строку, используя не- ─────────────── сколько различных стилей печати. Затем программная строка 50 позволяет вызвать макрокоманду, определенную в примере 21. 10 LPRINT CHR$(27);"4"; ' "Италик" 20 LPRINT CHR$(27);"G"; ' Двойной удар 30 LPRINT CHR$(14); ' Расширенная печать 40 LPRINT "TESTING ONE, TWO, THREE" 50 LPRINT CHR$(27);"%"; ' Вызов макрокоманды 60 LPRINT "TESTING FOUR, FIVE, SIX" VII.4.6. Д р у г и е п о л е з н ы е к о м а н д ы Все правила достойного поведения давным-давно известны, остановка за малым - за умением ими пользоваться. Б.Паскаль. Мысли Предлагаем Вашему вниманию следующую таблицу: ┌──────────────────────────────────┬────────────────────────────────────┐ │ Ф у н к ц и я │ У п р а в л я ю щ и й к о д │ ├──────────────────────────────────┼────────────────────────────────────┤ │ Повторение символа │ CHR$(27);"R";"n1n2n3";CHR$(m) │ ├──────────────────────────────────┼────────────────────────────────────┤ │ Отмена последней строки │ │ │ ("стирание" последней строки в │ CHR$(24) │ │ буфере) │ │ ├──────────────────────────────────┼────────────────────────────────────┤ │ Установка печатающего устройства │ CHR$(19) │ │ в автономный режим ("OFF LINE") │ │ ├──────────────────────────────────┼────────────────────────────────────┤ │ Установка печатающего устройства │ CHR$(17) │ │ в неавтономный режим ("ON LINE") │ │ ├──────────────────────────────────┼────────────────────────────────────┤ │ Звучание звонка печатающего │ CHR$(7) │ │ устройства │ │ ├──────────────────────────────────┼────────────────────────────────────┤ │ Выключение из работы детектора │ CHR$(27);"p";"0" │ │ отсутствия бумаги │ │ ├──────────────────────────────────┼────────────────────────────────────┤ │ Включение в работу детектора │ CHR$(27);"p";"1" │ │ отсутствия бумаги │ │ ├──────────────────────────────────┼────────────────────────────────────┤ │ Инициализация печатающего │ CHR$(27);"c";"1" │ │ устройства │ │ └──────────────────────────────────┴────────────────────────────────────┘ Выполнение команды повторения символа ┌──────────────────────────────────────┐ │ LPRINT CHR$(27);"R";"n1n2n3";CHR$(m) │ , └──────────────────────────────────────┘ где n1,n2,n3 - цифры от 0 до 9, приводит к повторению n раз (n=100·n1+10·n2+n3) символа с кодом m. П р и м е р 24. α) LPRINT CHR$(27);"R120";"+" ─────────────── β) LPRINT CHR$(27);"R120";"+";CHR$(24) ┌────────────────────┐ Команда │ LPRINT CHR$(19) │ └────────────────────┘ приводит к установке печатающего устройства в автономный режим. При этом игнорируются все последующие символы и функциональные коды, кроме кода CHR$(17) , который служит для возвращения печатающего устройства в режим "ON LINE". Действие команды ┌────────────────────┐ │ LPRINT CHR$(17) │ └────────────────────┘ отличается от нажатия на кнопку "ON LINE", расположенную на принтере. Ког- да горит лампочка "ON LINE", то печатающее устройство "игнорирует" код CHR$(17). ┌─────────────────────┐ Команда │ LPRINT CHR$(7) │ └─────────────────────┘ "заставляет" печатающее устройство издавать звук в течение приблизительно 1/4 секунды. ┌───────────────────────────┐ Командой │ LPRINT CHR$(27);"p";"0" │ └───────────────────────────┘ отменяется сигнал, подаваемый детектором отсутствия бумаги. Сигнал отсут- ствия бумаги обычно заставляет звучать звонок печатающего устройства и ос- танавливает печать до тех пор, пока не будет вставлена бумага. ┌───────────────────────────┐ Команда │ LPRINT CHR$(27);"p";"1" │ └───────────────────────────┘ восстанавливает функции детектора отсутствия бумаги. Команда и н и ц и а л и з а ц и и печатающего устройства ┌──────────────────────────┐ │ LPRINT CHR$(27);"c";"1" │ └──────────────────────────┘ повторно инициализирует печатающее устройство. Буфер печати при этом очи- щается.