ПРОФЕССИОНАЛЬНЫЙ ПОДХОД
Русификация - новые решения старой проблемы
© ИНФОРКОМ, Москва, 1994.
Вот уже примерно десятилетие прошло с того момента, как "Спектрум" начал "триумфальное шествие" по нашей стране. Но до сих пор более или менее приемлемо не решен один из основных вопросов "Спектрум-Бейсика" - это его русификация. Вообще-то, существует масса способов и приёмов, чтобы заставить компьютер печатать по-русски, но у всех у них те или иные недостатки. Рассмотрим некоторые из них (ну, русификацию с помощью UDG-символов здесь рассматривать не будем, из-за практической малопригодности для серьезного дела).
Итак, первый приём, предусмотренный операционной системой - загружаемый символьный набор. Это, казалось бы, решение всех проблем: печатай хоть русским, хоть каким угодно шрифтом, переключился на загруженный символьный набор и печатай, что хочешь. Но, в том-то и дело, что надо переключаться - при помощи POKE или GO SUB, а для этого приходится разбивать фразу на русские и английские слова и выводить их при помощи отдельных операторов PRINT, а между ними-то и расставлять те самые POKE или GO SUB, переключающие символьные наборы. Зачастую, к этому приходится прибегать через слово. Да и вид листинга программы получается какой-то несуразный. Либо корявые токены и системные сообщения, напечатанные русскими буквами, либо нечитаемый русский текст, напечатанный английскими буквами. Все это выглядит не очень симпатично, хотя мы все к этому уже привыкли; а что делать? К тому же если не хочешь расставлять POKE или GO SUB, тогда есть упрощенный вариант - печатай только заглавными русскими и латинскими (это наш типовой способ русификации при помощи русско-латинского символьного набора "НС" в кодировке КОИ-7 по стандарту ASCII). А, в общем, русификация при помощи загружаемого символьного набора, хотя и не так удобна, как хотелось бы, но, в принципе, вполне приемлема, тат как конечная цель все-таки достигается.
Существует более "крутой", глобальный вариант русификации - при помощи нового ПЗУ. Вот здесь все, как по маслу: нажал кнопку и печатай, хоть русским, хоть латинским, хоть в одном операторе PRINT, хоть в разных, хоть заглавными, хоть строчными. И курсор, и листинг выглядят так, как надо. Ну, в общем, предел мечтаний. Но только до тех пор, пока сидишь за своим, русифицированным таким способом компьютером. А как только захотел показать другу только-что сделанную программу - стоп! У него-то стандартное ПЗУ. Так что способ этот хорош только для несоизмеримо малого числа компьютеров. Да и то, не всегда. Где-то из-за нового ПЗУ интересная фирменная программа перестает работать, где-то музыки нет и т.д. и т.п., в общем - несовместимость. Стандартное ПЗУ - это объективная реальность, от этого никуда не уйти, поэтому вариант с новым ПЗУ на деле оказывается не так уж хорош.
В новом ПЗУ для переключения в русский регистр и печати русских букв применяются новые канальные процедуры ввода/вывода. Из этого непосредственно следует следующий способ русификации - при помощи каналов и потоков. Стандартно, к потоку #1 подключена процедура ввода KEY-INPUT (#10A8) и процедура печати PRINT-OUT (#09F4). К потоку #2 подключена та же процедура печати. Если мы создадим для клавиатуры новую процедуру ввода, обеспечивающую переход в русский регистр по нажатию какой-либо клавиши или комбинации клавиш, а для экрана -новую процедуру вывода для обеспечения перехода к печати русских букв (изменение значения CHARS, определяющего текущий символьный набор), то, подключив эти процедуры к стандартным потокам, обслуживающим клавиатуру (#1) и экран (#2), мы можем реализовать удобный способ русификации. И всё будет замечательно: и попереключаться в РУС. и ЛАТ. можно будет вдоволь в каждом операторе PRINT, и листинг будет смотреться так, как надо, и будут доступны и заглавные и строчные и русские и латинские буквы, но все это - только до первого оператора CLS или CLEAR или до запроса "scroll?" или до нажатия ENTER для получения автоматического листинга - во всех этих случаях происходит очистка экрана (или служебного экрана - нижних двух строк) и восстановление стандартного подключения каналов к потокам. Можно, конечно, в программах после каждого CLS производить заново подключение новых процедур при помощи тех же GO SUB, но редактирование Бейсик-программы станет практически невозможным, так как восстановление стандартного включения каналов будет происходить после каждого нажатия ENTER.
В своё время мы занимались таким способом русификации, были разработаны и реализованы новые канальные процедуры ввода/вывода, но дело намертво уперлось в "CLS" и получить практические результаты тогда не удалось. Процедуры были отложены "в долгий ящик" до лучших времён или идей. И вот, сейчас, мы можем обрадовать наших читателей тем, что такие времена настали благодаря письму с Украины, из г. Черкассы, его прислал Милищук Сергей Васильевич. Он предлагает для подключения новых канальных процедур ввода/вывода использовать прерывания 2 рода. Представьте себе: только операционная система после CLS восстановит стандартное подключение каналов, а мы, при помощи IM2, вновь будем подключать их так, как нам надо. И это будет происходить 50 раз в секунду. Так что стандартное включение "продержится" максимум 1/50 долю секунды, а затем вновь подключатся наши новые процедуры. Вот программа, реализующая такой способ.
Листинг 1.
00010 |
;DiCHARS by Milischuk S. |
00302 |
; Вывод |
на экран |
|
00020 |
;(C) 1994 |
|
00310 |
PRNOUT |
CALL #0B03 |
|
00040 |
ORG |
64389 |
00320 |
|
CALL |
CHR |
|
00050 |
NEW DEFW |
#FC00 |
00330 |
|
CP |
#20 |
|
00052 |
; Запуск программы |
00340 |
|
JP |
NC,#0AD9 |
|
00054 |
; RANDOMIZE USR |
64391 |
00350 |
|
CP |
6 |
|
00060 |
IM2 DI |
|
00360 |
|
JP |
C,#0A69 |
|
00070 |
LD |
A, #FB |
00370 |
|
CP |
#18 |
|
00080 |
LD |
I,A |
00380 |
|
JP |
NC,#0A6 9 |
|
00090 |
IM |
2 |
00390 |
|
LD |
HL,TCONTR-6 |
|
00100 |
EI |
|
00400 |
|
JP |
#0A07 |
|
00110 |
HALT |
|
00410 |
TCONTR |
DEFB |
18,20,22,24, |
17 |
00120 |
RET |
|
00420 |
|
DEFB |
16,15,23,13, |
12 |
00122 |
; Выход из программы |
00430 |
|
DEFB |
41,40,39,38 |
|
00124 |
; RANDOMIZE USR |
64401 |
00440 |
|
DEFB |
37,36,30,29 |
|
00130 |
IM1 IM |
1 |
00450 |
|
JP |
#0A5F |
|
00140 |
PUSH |
HL |
00460 |
|
JP |
#0A69 |
|
00150 |
LD |
HL,#09F4 |
00470 |
|
JP |
#0A23 |
|
00160 |
LD |
(#5CBB),HL |
00480 |
|
JP |
#0A3D |
|
00170 |
LD |
(#5CC5),HL |
00490 |
|
CALL |
HOME |
|
00180 |
POP |
HL |
00500 |
|
JP |
#0A4F |
|
00190 |
EI |
|
00510 |
PTV2 |
LD |
DE,PCONT |
|
00200 |
HALT |
|
00520 |
|
LD |
(#5C0F) ,A |
|
00210 |
RET |
|
00530 |
|
JR |
PCHANG |
|
00212 |
; Обслуживание |
|
00540 |
|
DEFW |
I NT |
|
00214 |
; прерываний 2 ; |
рода |
00550 |
P2OP |
LD |
DE,PTV2 |
|
00220 |
INT PUSH |
HL |
00560 |
|
JR |
PTV1 |
|
00230 |
LD |
HL,KEYIN |
00570 |
P1OP |
LD |
DE,PCONT |
|
00240 |
LD |
(#5CB8) , HL |
00580 |
PTV1 |
LD |
(#5C0E),A |
|
00250 |
LD |
HL,PRNOUT |
00590 |
PCHANG |
DI |
|
|
00260 |
LD |
(#5CB6),HL |
00600 |
|
JP |
#0A8 0 |
|
00270 |
LD |
(#5CBB),HL |
00610 |
PCONT |
EI |
|
|
00280 |
LD |
( #5CC5) ,HL |
00620 |
|
LD |
DE,PRNOUT |
|
00290 |
POP |
HL |
00630 |
|
JP |
#0A8A |
|
00300 |
JP |
#0038 |
00632 |
; Ввод |
|
|
|
00640 |
KEYIN |
BIT |
3,(IY+2) |
01180 |
|
EX |
DE, HL |
00650 |
|
CALL |
NZ,OUTPR |
01190 |
|
CALL |
OUTL2 |
00660 |
|
AND |
A |
01200 |
|
JP |
#1144 |
00670 |
|
BIT |
5,(IY+1) |
01210 |
OUTL2 |
SET |
0,(IY+1) |
00680 |
|
RET |
Z |
01220 |
|
PUSH |
DE |
00690 |
|
LD |
A,(#5C08) |
01230 |
|
EX |
DE, HL |
00700 |
|
RES |
5,(IY+1) |
01240 |
|
RES |
2,(IY+48) |
00710 |
|
PUSH |
AF |
01250 |
|
LD |
HL,#5C3B |
00720 |
|
BIT |
5,(IY+2) |
01260 |
|
RES |
2, (HL) |
00730 |
|
CALL |
NZ,#0D6E |
01270 |
|
BIT |
5, (IY+55) |
00740 |
|
POP |
AF |
01280 |
|
JR |
Z, L18 94 |
00750 |
|
CP |
#20 |
01290 |
|
SET |
2, (HL) |
00760 |
|
JP |
NC,#111B |
01300 |
L1894 |
LD |
HL,(#5C5F) |
00770 |
|
CP |
#10 |
01310 |
|
AND |
A |
00780 |
|
JR |
NC,KCONTR |
01320 |
|
SBC |
HL, DE |
00790 |
|
CP |
06 |
01330 |
|
JR |
NZ,L18A1 |
00800 |
|
JP |
NC,#10DB |
01340 |
|
LD |
A, #3F |
00810 |
|
LD |
B, A |
01350 |
|
CALL |
#18C1 |
00820 |
|
AND |
1 |
01360 |
L18A1 |
CALL |
#18E1 |
00830 |
|
LD |
C, A |
01370 |
|
EX |
DE, HL |
00840 |
|
LD |
A, B |
01380 |
|
LD |
A,(HL) |
00850 |
|
RRA |
|
01390 |
|
CALL |
CHR |
00860 |
|
ADD |
A, #12 |
01400 |
|
CALL |
#18B6 |
00870 |
|
JR |
KDATA |
01410 |
|
INC |
HL |
00880 |
|
JP |
#10DB |
01420 |
|
CP |
#0D |
00890 |
KCONTR |
LD |
B,A |
01430 |
|
JR |
Z,L18B4 |
00900 |
|
AND |
7 |
01440 |
|
EX |
DE, HL |
00910 |
|
LD |
C, A |
01450 |
|
CALL |
#1937 |
00920 |
|
LD |
A, #10 |
01460 |
|
JR |
L1894 |
00930 |
|
BIT |
3, B |
01470 |
L18B4 |
CALL |
HOME |
00940 |
|
JR |
NZ,KDATA |
01480 |
|
POP |
DE |
00950 |
|
INC |
A |
01490 |
|
RET |
|
00960 |
KDATA |
LD |
(IY-45),C |
01492 |
; Изменение символьного |
00970 |
|
LD |
DE,KNEXT |
01492 |
; набора |
если |
символ |
00980 |
|
DI |
|
01494 |
; "P" в |
граф. |
регистре |
00990 |
|
JR |
KCHANG |
01500 |
CHR |
CP |
#9F |
01000 |
KNEXT |
LD |
A,(#5C0D) |
01510 |
|
RET |
NZ |
01010 |
|
LD |
DE,KEYIN |
01520 |
|
PUSH |
HL |
01020 |
|
EI |
|
01530 |
|
PUSH |
DE |
01030 |
KCHANG |
JP |
#1113 |
01540 |
|
LD |
HL, (#5C3 6) |
01040 |
OUTPR |
CALL |
#0D4D |
01550 |
|
LD |
DE, (NEW) |
01050 |
|
RES |
3,(IY+2) |
01560 |
|
LD |
(NEW),HL |
01060 |
|
RES |
5,(IY+2) |
01570 |
|
LD |
(#5C3 6) ,DE |
01070 |
|
LD |
HL,(#5C8A) |
01580 |
|
POP |
DE |
01080 |
|
PUSH |
HL |
01590 |
|
POP |
HL |
01090 |
|
LD |
HL,(#5C3D) |
01592 |
; Вместо |
"Р" |
граф. |
01100 |
|
PUSH |
HL |
01592 |
; печатать "ПРОБЕЛ" |
01110 |
|
LD |
HL,#1167 |
01600 |
|
LD |
A,#20 |
01120 |
|
PUSH |
HL |
01610 |
|
RET |
|
01130 |
|
LD |
(#5C3D),SP |
01610 |
; Возврат к исходному |
01140 |
|
LD |
HL, (#5C82 ) |
01612 |
; символьному |
набору |
01150 |
|
PUSH |
HL |
01620 |
HOME |
PUSH |
HL |
01160 |
|
SCF |
|
01630 |
|
LD |
HL,#3C00 |
01170 |
|
CALL |
#1195 |
01640 |
|
LD |
(#5C3 6) ,HL |
01650 LD HL,#FC00 01670 POP HL
01660 LD (NEW),HL 01680 RET
Обратите внимание на строки 260-280. Они рассчитаны на магнитофонный вариант Спектрума. Для дискового их надо изменить:
00260 LD (#5D2 6),HL
00270 LD (#5D2B),HL
00280 LD (#5D35),HL
Хотя канал принтера можно к новой процедуре и не подключать, поэтому вместо команды в строке 280 можно поставить три команды NOP.
Запуск программы происходит при выполнении RANDOMIZE USR 64391 - при этом включается режим прерываний 2 рода, подключающий новые процедуры ввода/вывода к стандартным потокам. Русский символьный набор расположен с адреса #FC00+#0100=#FD00=64768. Переключение символьного набора происходит при вводе с клавиатуры символа "Р" в графическом регистре (код=#9F). При этом процедура устроена так, что вместо графического "Р" печатается " пробел".
Перед обращением к дисководу или в иных случаях, когда требуется отключить режим IM2, это может быть выполнено командой RANDOMIZE USR 64401.
Конечно, ничего не даётся даром. Предлагаемый способ имеет и свои недостатки. Так, после оператора CLS перед первым оператором PRINT должно успеть произойти прерывание, прежде чем что-то будет напечатано на экране - иначе будут подключены ещё стандартные канальные процедуры ввода/вывода. Практически реализовать это можно, введя (если надо) после CLS задержку на одно прерывание - 1/50 секунды. PAUSE 1 - вполне для этого подходит. Сложнее дела обстоят с оператором INPUT. Как известно, в момент выполнения этого оператора происходит очистка служебного экрана - двух нижних строк - со всеми вытекающими последствиями в смысле отключения новых канальных процедур ввода/вывода. И вводом PAUSE 1 здесь проблему не решить, так как очистка экрана происходит именно в момент исполнения оператора INPUT. Поэтому приходится идти на ухищрения другого рода - заставить компьютер "долго думать", выполняя INPUT, чтобы за это время успело произойти прерывание. Сергей Васильевич советует сделать это, например, так:
INPUT CHR$(COS 0*8);" ZX_PEBKl_"
здесь символ "_" обозначает переключатель шрифтов - "Р" в графическом регистре. Относительно долгое вычисление COS, казалось бы, совсем ненужное в операторе INPUT, приводит к той самой задержке, благодаря которой успевают подключиться новые канальные процедуры. Но к оператору INPUT мы ещё вернёмся.
Хотя программа, приведенная Сергеем Васильевичем, не лишена недостатков (например, неудобное переключение РУС/ЛАТ при помощи перехода в графический регистр, а затем обратно, да и печать при этом пробела лишает возможности слитного написания русских и латинских символов), но это уже не столь важно. Главное - он предложил идею: как при помощи IM2 бороться с подключением стандартных канальных процедур ввода/вывода во время CLS. Вот тут-то и вспомнили мы о том, что где-то "в долгом ящике" лежат разработанные давным-давно процедуры ввода/вывода, предназначенные для русификации. Теперь пришло время, смахнув пыль с этих записей, извлечь их на свет Божий. Далее мы приводим наш вариант русификации при помощи канальных процедур ввода/вывода, который нам удалось довести до рабочего состояния благодаря письму Сергея Васильевича. Собственно не "процедур", а "процедуры", так как процедура KEY-INPUT не изменена, но об этом - чуть позже.
Решено было использовать следующие "шрифтовые" комбинации клавиш: SYMBOL SHIFT + ENTER - включение русского шрифта; SYMBOL SHIFT + SPACE - включение латинского шрифта.
По идее, новая канальная процедура ввода должна перехватывать нажатие заданных шрифтовых комбинаций клавиш. При разработке процедуры встал вопрос, какие коды использовать для этого. Здесь надо внести некоторую ясность. Надо четко различать понятия: "код клавиши", "вводимый код", "печатный код" и "управляющий код". И, в связи с этим, самое время сделать небольшое отступление.
Некоторые подробности, касающиеся символьных кодов.
Код клавиши - это входной параметр, а вводимый код - выходной параметр канальной процедуры ввода KEY-INPUT. Если мы вводим букву, цифру, символ или токен, то код клавиши является и вводимым кодом. Вводимые коды с 32 по 255 являются печатными кодами. А вот с кодами меньше 32 ситуация иная. Например, при нажатии клавиши INV.VIDEO на вход процедуры KEY-INPUT подается код клавиши=5; при этом на выходе из процедуры KEY-INPUT для ввода в текст Бейсик-строки выдаются управляющие коды: CHR$ 20; CHR$ 1, а отнюдь не CHR$ 5 (который для печати не используется). Запустите Бейсик-программу: 10 PAUSE 0: PRINT CODE INKEY$: GO TO 10
Нажмите клавишу INV.VIDEO - на экране напечатается "5". Остановите программу и выполните PRINT CHR$ 5. Напечатается "?" (непечатаемый код). В любом справочнике по " Спектруму" Вы сможете найти значения кодов клавиш с 4 по 15 - это редактирующие клавиши. А что же коды клавиш с 0 по 3 и с 16 по 31? Как правило, в справочниках их нет. Выходит, они не используются? Нет, это неверно. Эти коды используются канальной процедурой KEY-INPUT при нажатии цифровых клавиш в режиме EXTEND MODE - благодаря им Вы можете вставлять непосредственно в текст управляющие коды INK, PAPER, BRIGHT и FLASH. Так, например, при нажатии в режиме EXT.MODE клавишей CAPS SHIFT + 1, на вход в процедуру KEY-INPUT будет подан код клавиши 25, благодаря которому на выходе из процедуры KEY-INPUT мы получим результат: в текст Бейсик-строки будет вставлена последовательность управляющих кодов: CHR$ 16; CHR$ 1, что даст INK 1. Полный перечень кодов клавиш приведен в таблице 1.
При нажатии клавиш редактирования, имеющих коды с 6 по 15 выполняется определенное редактирующее действие. При нажатии комбинаций клавиш, дающих коды клавиш 0 - 5 и 16 - 31, процедура KEYINPUT вводит в текст Бейсик-строки соответствующие управляющие коды INK, PAPER, INVERSE, BRIGHT и FLASH. Перечень этих управляющих кодов приведен в таблице 2 (не путать с кодами клавиш из таблицы 1).
Из этих таблиц вытекают два вывода.
1. Для переключения шрифтов можно использовать вводимые в текст Бейсик-строки неиспользуемые управляющие коды (из таблицы 2). Как видим, их более чем достаточно. Было решено переключение шрифтов выполнять однобайтовыми управляющими кодами (в отличие, скажем, от двухбайтовых INVERSE, BRIGHT и т.п.). Мы приняли за основу управляющие коды 4 и 5 для включения ЛАТ. и РУС. регистров соответственно.
Здесь, конечно, тоже желательно придерживаться какого-то стандарта. Поэтому мы просим наших читателей, имеющих русифицированные ПЗУ (использующиеся, например, в компьютерах "Дельта-С", и других) сообщить нам, какие управляющие коды используются там для переключения шрифтов. Благодаря такому соответствию удастся достичь совместимости с готовыми русскими Бейсик-программами, набранными при помощи любых русифицированных ПЗУ.
2. Не существует свободных кодов клавиш, к которым можно было бы "привязать" шрифтовые комбинации клавиш SYMBOL SHIFT + ENTER и SYMBOL SHIFT + SPACE. Предположим, что мы захотим использовать коды клавиш 4 и 5 - тогда мы лишимся возможности вводить с клавиатуры управляющие коды инверсии INV.VIDEO и TR.VIDEO (см. таблицу 1). Мы можем условиться, что это будут коды клавиш 2 и 3, но тогда мы не сможем с клавиатуры вводить управляющие коды яркости и т.д. Поэтому, для обеспечения совместимости на уровне использования управляющих клавиш было принято принципиальное решение: оставить канальную процедуру ввода KEY-INPUT без изменения, а факт нажатия SYMBOL SHIFT + ENTER и SYMBOL SHIFT + SPACE перехватывать на уровне подпрограммы обслуживания прерывания. Эта же подпрограмма будет и вводить в текст редактируемой Бейсик-строки или INPUT-строку шрифтовые
Итак, опрос шрифтовых комбинаций клавиш и вставка шрифтовых управляющих кодов будет происходить на уровне процедуры обслуживания прерываний 2 рода. Но при этом необходимо учесть, в каком режиме находится Спектрум. Если идёт редактирование Бейсик-строки или INPUT-строки (работает редактор Бейсика), то надо всё это делать. Если же идёт исполнение Бейсик-программы (запуск по команде RUN, при этом работает интерпретатор Бейсика), то отработка нажатия шрифтовых клавиш должна быть заблокирована. Процедура обработки прерывания 2 рода должна определять это.
Теперь можно переходить непосредственно к листингу программы "Резидентный русификатор".
управляющие коды 4 или 5. А вот канальная процедура вывода PRINT-OUT - новая. Она обеспечивает обработку неиспользуемых ранее управляющих кодов 4 и 5.
Таблица 1._ Таблица 2_
Управл яющий код |
Значение |
0 |
не используется |
1 |
не используется |
2 |
не используется |
3 |
не используется |
4 |
не используется |
5 |
не используется |
6 |
COMMA CONTROL |
7 |
не используется |
8 |
BACK (LEFT) |
9 |
не используется |
10 |
не используется |
11 |
не используется |
12 |
не используется |
13 |
CARRIAGE RETURN |
14 |
не используется |
15 |
не используется |
16 |
INK CONTROL |
17 |
PAPER CONTROL |
18 |
FLASH CONTROL |
19 |
BRIGHT CONTROL |
20 |
INVERSE CONTROL |
21 |
OVER CONTROL |
22 |
AT CONTROL |
23 |
TAB CONTROL |
24 |
не используется |
25 |
не используется |
26 |
не используется |
27 |
не используется |
28 |
не используется |
29 |
не используется |
30 |
не используется |
31 |
не используется |
Код клавиши |
Комбинация клавиш |
Действие |
0 |
E.MODE; CS+8 |
FLASH 0 |
1 |
E.MODE; CS+9 |
FLASH 1 |
2 |
E.MODE; 8 |
BRIGHT 0 |
3 |
E.MODE; 9 |
BRIGHT 1 |
4 |
CS + 3 |
INVERSE 0 |
5 |
CS + 4 |
INVERSE 1 |
6 |
CS + 2 |
CAPS LOCK |
7 |
CS + 1 |
EDIT |
8 |
CS + 5 |
LEFT |
9 |
CS + 8 |
RIGHT |
10 |
CS+6 |
DOWN |
11 |
CS + 7 |
UP |
12 |
CS + 0 |
DELETE |
13 |
ENTER |
ENTER |
14 |
CS + SS |
EXT.MODE |
15 |
CS + 9 |
GRAPH |
16 |
E.MODE; 0 |
PAPER 0 |
17 |
E.MODE; 1 |
PAPER 1 |
18 |
E.MODE; 2 |
PAPER 2 |
19 |
E.MODE; 3 |
PAPER 3 |
20 |
E.MODE; 4 |
PAPER 4 |
21 |
E.MODE; 5 |
PAPER 5 |
22 |
E.MODE; 6 |
PAPER 6 |
23 |
E.MODE; 7 |
PAPER 7 |
24 |
E.MODE; CS+0 |
INK 0 |
25 |
E.MODE; CS+1 |
INK 1 |
26 |
E.MODE; CS+2 |
INK 2 |
27 |
E.MODE; CS+3 |
INK 3 |
28 |
E.MODE; CS+4 |
INK 4 |
29 |
E.MODE; CS+5 |
INK 5 |
30 |
E.MODE; CS+6 |
INK 6 |
31 |
E.MODE; CS+7 |
INK 7 |
Листинг 2.
00001 |
; (С) |
ALANSOFT' |
94 . |
|
00520 |
|
LD |
(HL),E |
00002 |
; "Resident-Rusifikator" |
00530 |
|
INC |
HL |
00010 |
|
ORG |
63000 |
00540 |
|
LD |
(HL),D |
00020 |
|
ENT |
|
|
00550 |
|
INC |
HL |
00030 |
; |
|
|
|
00560 |
|
INC |
HL |
00040 |
START |
JP |
START1 |
00570 |
|
INC |
HL |
00050 |
;----- |
|
|
|
00580 |
|
INC |
HL |
00060 |
STOP |
DI |
|
|
00590 |
|
LD |
(HL),E |
00070 |
|
LD |
HL, |
(#5C4F) |
00600 |
|
INC |
HL |
00080 |
|
LD |
(HL |
) ,#F4 |
00610 |
|
LD |
(HL),D |
00090 |
|
INC |
HL |
|
00620 |
INT1 |
LD |
HL,(#5C78) |
00100 |
|
LD |
(HL |
) ,#09 |
00630 |
|
INC |
HL |
00110 |
|
INC |
HL |
|
00640 |
|
LD |
(#5C7 8) ,HL |
00120 |
|
INC |
HL |
|
00650 |
|
LD |
A, H |
00130 |
|
INC |
HL |
|
00660 |
|
OR |
L |
00140 |
|
INC |
HL |
|
00670 |
|
JR |
NZ, INT2 |
00150 |
|
LD |
(HL |
) ,#F4 |
00680 |
|
INC |
(IY+64) |
00160 |
|
INC |
HL |
|
00690 |
INT2 |
LD |
HL,(#5CB2) |
00170 |
|
LD |
(HL |
) ,#09 |
00700 |
|
LD |
DE,(#5C3D) |
00180 |
|
IM |
1 |
|
00710 |
|
INC |
DE |
00190 |
|
EI |
|
|
00720 |
|
INC |
DE |
00200 |
|
HALT |
|
|
00730 |
|
INC |
DE |
00210 |
|
RET |
|
|
00740 |
|
OR |
A |
00220 |
;----- |
|
|
|
00750 |
|
SBC |
HL, DE |
00230 |
START1 |
DI |
|
|
00760 |
|
LD |
A, H |
00240 |
|
LD |
DE, |
INT |
00770 |
|
OR |
L |
00250 |
|
LD |
HL, |
#FDFD |
00780 |
|
JR |
Z, INT8 |
00260 |
|
LD |
(HL |
) , #C3 |
00790 |
INT3 |
LD |
A,#7F |
00270 |
|
INC |
HL |
|
00800 |
|
IN |
A,(#FE) |
00280 |
|
LD |
(HL |
) ,E |
00810 |
|
BIT |
1,A |
00290 |
|
INC |
HL |
|
00820 |
|
JR |
NZ, INT7 |
00300 |
|
LD |
(HL |
) ,D |
00830 |
|
LD |
A,(KEY) |
00310 |
|
INC |
HL |
|
00840 |
|
OR |
A |
00320 |
|
LD |
(HL |
) ,#FD |
00850 |
|
JR |
NZ, INT6 |
00330 |
|
LD |
D, H |
|
00860 |
|
LD |
A, #7F |
00340 |
|
LD |
E, L |
|
00870 |
|
IN |
A,(#FE) |
00350 |
|
INC |
DE |
|
00880 |
|
BIT |
0,A |
00360 |
|
LD |
BC, |
256 |
00890 |
|
JR |
NZ, INT4 |
00370 |
|
LDIR |
|
|
00900 |
|
LD |
A, 4 |
00380 |
|
LD |
A, #FE |
|
|
; LAT |
|
00390 |
|
LD |
I,A |
|
00910 |
|
JR |
INT5 |
00400 |
|
IM |
2 |
|
00920 |
INT4 |
LD |
A,#BF |
00410 |
|
LD |
BC, |
(#5C3 6) |
00930 |
|
IN |
A,(#FE) |
00420 |
|
EI |
|
|
00940 |
|
BIT |
0,A |
00430 |
|
HALT |
|
|
00950 |
|
JR |
NZ, INT7 |
00440 |
|
RET |
|
|
00960 |
|
LD |
A, 5 |
00450 |
|
|
|
|
|
|
; RUS |
|
00460 |
INT |
PUSH |
AF |
|
00970 |
INT5 |
LD |
(KEY),A |
00470 |
|
PUSH |
HL |
|
00980 |
|
CALL |
#0F81 |
00480 |
|
PUSH |
BC |
|
00990 |
|
LD |
D, 0 |
00490 |
|
PUSH |
DE |
|
01000 |
|
LD |
E,(IY-1) |
00500 |
|
LD |
HL, |
(#5C4F) |
01010 |
|
LD |
HL,#0 0C8 |
00510 |
|
LD |
DE, |
PRINT |
01020 |
|
CALL |
#03B5 |
01030 |
|
CALL |
#111D |
|
01450 |
|
DEFB |
PO1OP-TAB-18 |
01040 |
INT6 |
JP |
#004D |
|
01460 |
|
DEFB |
PO1OP-TAB-19 |
01050 |
INT7 |
XOR |
A |
|
01470 |
|
DEFB |
PO1OP-TAB-2 0 |
01060 |
|
LD |
(KEY) , A |
|
01480 |
|
DEFB |
PO1OP-TAB-21 |
01070 |
INT8 |
JP |
#004A |
|
01490 |
|
DEFB |
PO2OP-TAB-22 |
01080 |
;------ |
|
|
|
01500 |
|
DEFB |
PO2OP-TAB-23 |
01090 |
KEY |
DEFB |
0 |
|
01510 |
;------ |
|
|
01100 |
|
|
|
|
01520 |
QUEST |
JP |
#0A69 |
01110 |
PRINT |
CP |
#20 |
|
01530 |
COMMA |
JP |
#0A5F |
01120 |
|
JR |
C,PRN1 |
|
01540 |
LEFT |
JP |
#0A23 |
01130 |
|
CP |
#A5 |
|
01550 |
RIGHT |
JP |
#0A3D |
01140 |
|
CALL |
NC,LAT |
|
01560 |
ENTER |
JP |
#0A4F |
01150 |
|
LD |
HL,ALPH |
|
01570 |
POTV2 |
LD |
DE,POCONT |
01160 |
|
BIT |
0, (HL) |
|
01580 |
|
LD |
(#5C0F) ,A |
01170 |
|
CALL |
Z,CHRLAT |
|
01590 |
|
JR |
POCHAN |
01180 |
|
CALL |
NZ, CHRRUS |
|
01600 |
PO2OP |
LD |
DE,POTV2 |
01190 |
|
CALL |
#0B03 |
|
01610 |
|
JR |
POTV1 |
01200 |
|
JP |
#0AD9 |
|
01620 |
PO1OP |
LD |
DE,POCONT |
01210 |
PRN1 |
CALL |
#0B03 |
|
01630 |
POTV1 |
LD |
(#5C0E),A |
01220 |
|
CP |
#18 |
|
01640 |
POCHAN |
DI |
|
01230 |
|
JR |
NC,QUEST |
|
01650 |
|
JP |
#0A8 0 |
01240 |
|
LD |
HL,TAB |
|
01660 |
POCONT |
EI |
|
01250 |
|
JP |
#0A07 |
|
01670 |
|
LD |
DE,PRINT |
01260 |
;------ |
|
|
|
01680 |
|
JP |
#0A8A |
01270 |
TAB |
DEFB |
QUEST-TAB- |
0 |
01690 |
;------ |
|
|
01280 |
|
DEFB |
QUEST-TAB- |
1 |
01700 |
LAT |
LD |
HL,ALPH |
01290 |
|
DEFB |
QUEST-TAB- |
2 |
01710 |
|
RES |
0,(HL) |
01300 |
|
DEFB |
QUEST-TAB- |
3 |
01720 |
CHRLAT |
LD |
HL,FNTLAT-2 5 6 |
01310 |
|
DEFB |
LAT-TAB-4 |
|
01730 |
|
JR |
LO |
01320 |
|
DEFB |
RUS-TAB-5 |
|
01740 |
RUS |
LD |
HL,ALPH |
01330 |
|
DEFB |
COMMA-TAB-- |
6 |
01750 |
|
SET |
0,(HL) |
01340 |
|
DEFB |
QUEST-TAB- |
7 |
01760 |
CHRRUS |
LD |
HL,FNTRUS-256 |
01350 |
|
DEFB |
LEFT-TAB-8 |
|
01770 |
LO |
LD |
(#5C3 6),HL |
01360 |
|
DEFB |
RIGHT-TAB- |
9 |
01780 |
|
RET |
|
01370 |
|
DEFB |
QUEST-TAB- |
10 |
01790 |
;------ |
|
|
01380 |
|
DEFB |
QUEST-TAB- |
11 |
01800 |
ALPH |
DEFB |
0 |
01390 |
|
DEFB |
QUEST-TAB- |
12 |
|
|
; LAT |
|
01400 |
|
DEFB |
ENTER-TAB- |
13 |
01810 |
|
|
|
01410 |
|
DEFB |
QUEST-TAB- |
14 |
01820 |
FNTRUS |
DEFS |
768 |
01420 |
|
DEFB |
QUEST-TAB- |
15 |
01830 |
;------ |
|
|
01430 |
|
DEFB |
PO1OP-TAB- |
16 |
01840 |
FNTLAT |
DEFS |
768 |
01440 |
|
DEFB |
PO1OP-TAB- |
17 |
|
|
|
|
Инициализация русификатора (включение режима прерываний 2 рода) выполняется командой RANDOMIZE USR 63000. Такой адрес процедуры был выбран для легкости запоминания, адрес восстановления прерываний 1 рода - 63003, что тоже легко запоминается.
Процедура инициализации START (START1) учитывает несовместимость по прерываниям IM 2 некоторых компьютеров, о чем мы неоднократно сообщали на страницах ZX-РЕВЮ (см. например РЕВЮ за 1994 год, № 1 стр. 24, № 4 стр. 52). При инициализации создается 257-байтовый буфер, начиная с #FE00 по #FF00 включительно, заполненный кодом #FD, так что при векторе прерывания, равном #FE, независимо от значения младшего байта, считается один и тот же адрес процедуры обработки прерывания: #FDFD. А по этому адресу находится безусловный переход на реальный адрес процедуры INT. Кроме того, регистровая пара ВС загружается значением системной переменной CHARS. Это абсолютно ни на что не влияет, но может оказаться в некоторых случаях полезно: подав
после инициализации команду PRINT USR 63000, мы получим значение CHARS латинского символьного набора, а, подав команду PRINT "<SYMB.SHIFT+ENTER>"; USR 63000 получим значение CHARS русского символьного набора.
Процедуру STOP (RANDOMIZE USR 63003) необходимо использовать во всех случаях, когда недопустимо использование прерываний 2 рода, например, перед тем, как обращаться к дисководу. После завершения выполнения команды TR-DOS вновь инициализируйте систему командой RANDOMIZE USR 63000.
Теперь подробнее о процедуре INT (строка 460). Многие её элементы и точки входа соответствуют процедуре ПЗУ RST #38, поэтому для сравнения можно дисассемблировать интересующий фрагмент ПЗУ с адреса #0038 по #0052 включительно.
После сохранения на стеке значений регистров, происходит замена канальной информации. Причем, безразлично, используете Вы магнитофон или дисковод - процедура учитывает это, используя значение системной переменной CHANS (строка 500). Вместо процедуры ПЗУ PRINTOUT задается (при помощи регистра DE) новая процедура PRINT для потоков #0 и #2 (для принтера -поток #3 - новая процедура не подключается, так как должен быть предварительно определен тип интерфейса и принцип переключения РУС/ЛАТ для каждого конкретного принтера).
Процедура INT1 дублирует ПЗУ - эта часть обеспечивает наращивание системной переменной FRAMES - внутренних часов Спектрума.
Процедура INT2 определяет, в каком режиме находится Спектрум (об этом говорилось выше). Определяется это путем сравнения значения системной переменной ERR_SP (в регистре DE) со значением RAMTOP (в регистре HL). Если значение ERR_SP на три байта меньше, чем значение RAMTOP, значит, Спектрум находится в режиме выполнения Бейсик-программы. Иначе - в режиме редактирования (кстати сказать, это обстоятельство было выяснено путем просмотра содержимого ERR_SP при помощи резидентного отладчика TRACER, опубликованного в ZX-PEB^^93, стр.33).
Если Спектрум находится не в режиме редактирования Бейсик-строки или INPUT-строки, то выполняется переход через INT8 в соответствующую точку ПЗУ для штатного вызова процедуры опроса клавиатуры KEY-INT. Иначе - продолжение работы.
Процедура INT3 выполняет сканирование правого нижнего полуряда клавиатуры и проверяет, нажата ли клавиша SYMBOL SHIFT. Если нет, то происходит переход на INT7 - здесь обнуляется вспомогательная системная ячейка KEY - она регистрирует факт нажатия шрифтовой комбинации клавиш. Ее значение проверяется после проверки нажатия SYMBOL SHIFT (строки 830-850). Если ячейка не пуста, значит шрифтовая комбинация клавиш уже была зафиксирована в прошлом цикле прерываний и, следовательно, были выполнены все действия, связанные с переключением регистров. В этом случае выполняется переход через INT6 в точку завершения процедуры обработки прерывания. Таким образом, при нажатии шрифтовых комбинаций клавиш блокируется автоповтор -предотвращается многократный ввод шрифтовых управляющих кодов при удержании клавишей нажатыми длительное время.
Далее, если нажата клавиша SIMBOL SHIFT, проверяется нажатие SPACE (со строки 860). Если она не нажата, то переход на проверку нажатия ENTER - INT4. Иначе - в аккумулятор заносится управляющий код 4, предназначенный для включения регистра ЛАТ. При дальнейшем переходе на INT5 это значение заносится и в ячейку KEY для сигнализации о нажатии шрифтовой комбинации клавиш при следующем прерывании.
В том случае, если нажата не SPACE, а ENTER, в аккумулятор и ячейку KEY заносится управляющий код 5, предназначенный для включения регистра РУС.
Далее, вызовом подпрограммы ПЗУ ADD-CHAR (строка 980) выполняется выделение одного байта памяти в редактируемой области и вставка вводимого кода в редактируемую Бейсик-строку или INPUT-строку. При этом, как и при вводе любого другого символа, выдается стандартный звуковой сигнал (строки 990-1020) и происходит перепечатка редактируемой строки в нижней части экрана вызовом процедуры ED-COPY (строка 1030), как это всегда происходит при вводе очередного символа с клавиатуры. На этом обработка прерывания заканчивается.
Теперь рассмотрим новую канальную процедуру вывода PRINT, которая подключается вместо стандартной процедуры ПЗУ PRINT-OUT. Многие её элементы и точки входа соответствуют процедуре ПЗУ #09F4. Для сравнения можно дисассемблировать фрагмент ПЗУ с адреса #09F4 по #0A10 включительно.
Прежде всего (строка 1110) проверяется, является ли обрабатываемый код печатным или управляющим кодом. Если это управляющий код, то переход на PRN1, если печатный код -
дальнейшая проверка. Если этот печатный код является токеном, то должен быть выведен на печать английскими буквами, для этого происходит вызов подпрограммы переключения регистра LAT. Далее выполняется проверка текущего состояния шрифтового регистрового флага - нулевого бита системной ячейки ALPH. Его равенство нулю свидетельствует о включенном регистре ЛАТ. В этом случае происходит изменение текущего значения CHARS, соответствующее латинскому символьному набору. Если значение флага ALPH не равно нулю, задается значение CHARS русского символьного набора.
Далее (строка 1190) следует вызов подпрограммы ПЗУ PO-FETCH для ввода координат позиции печати из соответствующих системных переменных, как это делается в стандартной процедуре PRINT-OUT.
Изложенное выше касалось печатных кодов. Для обработки управляющих кодов предназначена процедура PRN1. Здесь после вызова PO-FETCH, если символ больше или равен #18, происходит переход на печать "?". Для управляющих кодов с 0 по #17 происходит расчет дальнейшего адреса по таблице аналогично тому, как это делается в процедуре ПЗУ #09F4. Здесь в строках 1310, 1320 задается отработка шрифтовых управляющих кодов. Остальные процедуры, задаваемые при помощи таблицы TAB, используют соответствующие процедуры ПЗУ или построены аналогично им (строки 1520-1680).
Подпрограммы LAT и RUS занимаются непосредственно переключением символьных наборов с соответствующим изменением регистрового флага - 0 бита ячейки ALPH.
И, в заключение, о символьных наборах. Приведенная процедура использует два стилизованных "утолщенных" символьных набора. Причем, для корректной работы необходимо обеспечить полное соответствие их первой трети, то есть символов с кодами с 32 по 63 включительно (символы и цифры).
Можно несколько сократить размер суммарного блока кодов, если использовать вместо латинского - символьный набор ПЗУ. При этом русский символьный набор должен иметь однотипный дизайн, а первая треть - символы и цифры - копировать символьный набор ПЗУ. Все изменения в процедуре сводятся к замене одной строки листинга: 018 4 0 FNTLAT EQU #3C0 0.
Как обычно, приводим шестнадцатиричный дамп блока кодов резидентного русификатора.
F618 |
C3 |
32 |
F6 |
F3 |
2A |
4F |
5C |
36 |
F7 |
F620 |
F4 |
23 |
36 |
09 |
23 |
23 |
23 |
23 |
F8 |
F628 |
36 |
F4 |
23 |
36 |
09 |
ED |
56 |
FB |
E8 |
F630 |
76 |
C9 |
F3 |
11 |
57 |
F6 |
21 |
FD |
D4 |
F638 |
FD |
36 |
C3 |
23 |
73 |
23 |
72 |
23 |
72 |
F640 |
36 |
FD |
54 |
5D |
13 |
01 |
00 |
01 |
2 F |
F648 |
ED |
B0 |
3E |
FE |
ED |
47 |
ED |
5E |
96 |
F650 |
ED |
4B |
36 |
5C |
FB |
76 |
C9 |
F5 |
3F |
F658 |
E5 |
C5 |
D5 |
2A |
4F |
5C |
11 |
CD |
80 |
F660 |
F6 |
73 |
23 |
72 |
23 |
23 |
23 |
23 |
E0 |
F668 |
73 |
23 |
72 |
2A |
78 |
5C |
23 |
22 |
A9 |
F670 |
78 |
5C |
7C |
B5 |
20 |
03 |
FD |
34 |
BF |
F678 |
40 |
2A |
B2 |
5C |
ED |
5B |
3D |
5C |
C7 |
F680 |
13 |
13 |
13 |
B7 |
ED |
52 |
7C |
B5 |
D6 |
F688 |
28 |
3F |
3E |
7F |
DB |
FE |
CB |
4F |
95 |
F690 |
20 |
33 |
3A |
CC |
F6 |
B7 |
20 |
2A |
D6 |
F698 |
3E |
7F |
DB |
FE |
CB |
47 |
20 |
04 |
5A |
F6A0 |
3E |
04 |
18 |
0A |
3E |
BF |
DB |
FE |
D0 |
F6A8 |
CB |
47 |
20 |
19 |
3E |
05 |
32 |
CC |
2A |
F6B0 |
F6 |
CD |
81 |
0F |
16 |
00 |
FD |
5E |
6A |
F6B8 |
FF |
21 |
C8 |
00 |
CD |
B5 |
03 |
CD |
E8 |
F6C0 |
1D |
11 |
C3 |
4D |
00 |
AF |
32 |
CC |
A1 |
F6C8 |
F6 |
C3 |
4A |
00 |
00 |
FE |
20 |
38 |
17 |
F6D0 |
16 |
FE |
A5 |
D4 |
39 |
F7 |
21 |
4F |
F3 |
F6D8 |
F7 |
CB |
46 |
CC |
3E |
F7 |
C4 |
48 |
E3 |
F6E0 |
F7 |
CD |
03 |
0B |
C3 |
D9 |
0A |
CD |
1B |
F6E8 |
03 |
0B |
FE |
18 |
30 |
1E |
21 |
F4 |
65 |
F6F0 |
F6 |
C3 |
07 |
0A |
18 |
17 |
16 |
15 |
0A |
F6F8 |
41 |
4A |
15 |
11 |
16 |
18 |
0E |
0D |
E8 |
F7 0 0 |
0C |
17 |
0A |
09 |
24 |
23 |
22 |
21 |
B7 |
F7 0 8 |
20 |
1F |
19 |
18 |
C3 |
69 |
0A |
C3 |
68 |
F710 |
5F |
0A |
C3 |
23 |
0A |
C3 |
3D |
0A |
6A |
F718 |
C3 |
4F |
0A |
11 |
32 |
F7 |
32 |
0F |
A6 |
F720 |
5C |
18 |
0B |
11 |
1B |
F7 |
18 |
03 |
D4 |
F728 |
11 |
32 |
F7 |
32 |
0E |
5C |
F3 |
C3 |
AB |
F7 3 0 |
80 |
0A |
FB |
11 |
CD |
F6 |
C3 |
8A |
CD |
F7 3 8 |
0A |
21 |
4F |
F7 |
CB |
86 |
21 |
50 |
62 |
F7 4 0 |
F9 |
18 |
08 |
21 |
4F |
F7 |
CB |
C6 |
48 |
F7 4 8 |
21 |
50 |
F6 |
22 |
36 |
5C |
C9 |
00 |
23 |
После набора сохраните полученный блок кодов командой: SAVE "rus"CODE 63000,312
Можете подгрузить символьные наборы: LOAD "chr rus" CODE 63312: LOAD "chr lat" CODE 64080
(или только первый - для варианта с одним символьным набором) и сохранить суммарный блок кодов:
SAVE "rus" CODE 63000,1848
(или SAVE "rus" CODE 63000,1080 для одного символьного набора)
Для запуска процедуры в работу можно воспользоваться простейшим Бейсик-загрузчиком: 10 CLEAR 62999: LOAD "rus"CODE
20 PRINT AT 11,2; INVERSE 1,-"START - RANDOMIZE USR 63000",-AT 13,2;" STOP - RANDOMIZE USR 63003",-#0,-FLASH 1;" Press any key to NEW ": P
AUSE 0 30 NEW
После нажатия клавиши и выполнения команды NEW, выполните RANDOMIZE USR 63000 и можете начинать работу, используя шрифтовые комбинации клавиш SYMBOL SHIFT + ENTER и SYMBOL SHIFT + SPACE.
Однако для готовых программ удобно загружать блок кодов русификатора и инициализировать его при старте программы, причем переделки существующих программ сводятся к минимуму, вместо традиционной загрузки русского символьного набора (LOAD "chr"CODE 64600) может быть следующее (автостарт программы со 2 строки):
1 GO TO 100
2 CLEAR 62999: LOAD "rus"CODE
3 RANDOMIZE USR 63000 100 ... Бейсик-программа
.:
Подведём итоги. Что нового имеет теперь пользователь? Один раз перед началом работы требуется загрузить и запустить процедуру в кодах: RANDOMIZE USR 63000. Благодаря этому появляется возможность использовать русские и латинские заглавные и строчные буквы.
Раскладка клавиатуры в русском регистре соответствует "ЯВЕРТЫ...", хотя, если подключить не только новую канальную процедуру PRINT-OUT, но и KEY-INPUT, можно реализовать любую раскладку клавиатуры. В русском регистре курсор изменяется: он принимает вид [Л] - для строчных и [Ц] - для заглавных букв. При вводе русского текста нет необходимости в конце русской фразы переключаться опять в латинский регистр (аналогично INVERSE VIDEO и TRUE VIDEO, чтобы не нарушать удобочитаемость листинга). Новая канальная процедура печати сделает это сама, встретив первый же токен. Благодаря этому листинг программы всегда читается так, как должен. Цветовые управляющие коды, а также CHR$ 6 (COMMA CONTROL) могут быть введены с клавиатуры как обычно и действуют корректно. Имеется возможность полной совместимости с любой версией русифицированных ПЗУ, что позволяет использовать программы, набранные с их помощью с минимальной адаптацией.
Но ничего не даётся даром. Как в адаптируемых, так и в набираемых заново программах, после CLS, как уже говорилось, может потребоваться вставка PAUSE 1. Больше хлопот доставляет оператор INPUT. Причём, если это просто INPUT a$, то проблемы вообще нет. Если же INPUT " string" ;a$ причём в выражении "string" встречаются переключатели шрифтов, то тут и возникает та самая проблема CLS. Здесь, как говорилось выше, надо каким-то образом заставить компьютер "долго думать". Это можно сделать, например, так: INPUT CHR$ SQR 16; "ENGLISH string";a$ или так: INPUT CHR$ SQR 25; "РУССКИИ текст"^. Относительно долгое вычисление SQR приводит к требуемой задержке. Сама же предварительная подача управляющих кодов 4 или 5 позволяет заранее переключить регистр, подготовив пользователю ввод либо латинским либо русским шрифтом (аналогично тому, как Вы заранее перед командой INPUT включаете или выключаете регистр CAPS LOCK, подавая команду POKE 23658,8 или POKE 23658,0).
Как видим, новая процедура является серьёзным прорывом в деле русификации Спектрум-Бейсика, хотя и имеет определенные недостатки. Слово Вам, уважаемые читатели. Как говорится, кто сможет, пусть сделает лучше. Мы готовы дать слово всем, кто поможет в решении этой проблемы.
AAA