РЕВЮ
N9 (9) 1991
МП "ИНФОРКОМ", 107241, МОСКВА, Б-241, а/я 37
СЕКРЕТЫ ПЗУ
(продолжение)
Процедуры редактора.
Редактор вызывается в двух случаях: из главного вычислительного блока - когда пользователь вводит в систему БЕЙСИК-программу и из процедур, занимающихся обработкой команда INPUT.
0F2C-0F2F EDITOR
Это точка входа. Здесь запоминается на машинном стеке содержимое системной переменной ERR-SP (23613,23614).
0F30-0F37 ED-AGAIN
В ERR-SP устанавливается адрес 107F, где расположена процедура обработки ошибок, возникающих при редактировании строк.
0F38-0F6B ED-LOOP
Организуется цикл, принимающий код нажатой клавиши и выполняется распределение работы по процедурам, в зависимости от того, что это за код.
Опрашивается клавиатура вызовом WAIT-KEY (15D4). Принятый код находится в аккумуляторе. Устанавливается продолжительность звукового сигнала по системной переменной PIP(23609) и его высота. Вызовом BEEPER (03B5) выдается звуковой сигнал, свидетельствующий о том, что клавиша нажата, после чего на стеке выставляется адрес начала этой процедуры (0F38), что и обеспечит работу в цикле.
Далее анализируется принятый от клавиши код.
Если он больше 16H, т.е. это печатный или графический символ или токен ключевого слова - переход на ADD-CHAR (0F81).
Если он равен 6, то это запятая оператора PRINT и выполняется переход туда же.
Если он меньше 10H, но больше 6, то это клавиша редактирования и переход выполняется в ED-KEYS (0F92).
Если код больше или равен 10H, но меньше 16H, то это цветовой код и переход на ED-CONTR (0F60). Обратите внимание, что после цветового кода должен идти еще один код (операнд), определяющий значение данного атрибута цвета.
Последний случай - если код равен 16H (AT) или 17H (TAB), после которых должны следовать два операнда, определяющие координаты позиции печати. Если идет обработка БЕЙСИК-строки (а это определяется по выключенному седьмому биту системной переменной FLAGX), то их не надо исполнять и выполняется переход на процедуру ED-IGNORE (101E).
Если же идет обработка INPUT, то их надо исполнить. Принимается первый операнд вызовом WAIT-KEY (15D4) и работа продолжается в следующей процедуре.
0F5C-0FB0 ED-CONTR
Здесь обрабатываются управляющие коды цвета, а также AT и TAB.
Scan, OCR & Spellcheck by NUK, km, Василий Кормилицын
Вызовом WAIT-KEY (15D4) вводится операнд (для кодов управления цветом он первый, а для AT и TAB - уже второй).
Вызовом MAKE-ROOM (1655) выделяется место в области памяти БЕЙСИКа для вставки этих управляющих кодов с операндами в БЕЙСИК-строку. Работа заканчивается переходом на ADD-CH-1 (0F8B)
0F81-0F8A ADD-CHAR
Задача - ввести принятый с клавиатуры символ в редактируемую Бейсик-строку или INPUT-строку. Выключением нулевого бита системной переменной MODE (23617) устанавливается курсор "K". Адрес курсора в экранном файле вводится из K-CUR(23643,23644) в регистровую пару HL и вызовом процедуры ONE-SPACE (1652) выделяется один байт памяти в редактируемой области для ввода туда принятого кода.
0F8B-0F91 ADD-CH-1
В выделенное место вставляется принятый код, запоминается положение курсора и выполняется возврат. Поскольку на стеке был выставлен адрес ED-LOOP (0F38), то это означает повторение цикла.
0F92-0F9F ED-KEYS
Сюда мы попадаем, если была нажата клавиша редактирования. Здесь в зависимости от того, что это была за клавиша, выполняется переход на соответствующую процедуру. Адрес перехода вычисляется с помощью нижележащей таблицы, в которой ведены "смещения" относительно базового адреса.
В качестве базового вводится адрес 0F99. Поиск по таблице исполняется прибавлением базового адреса к коду клавиши редактирования. Из полученного адреса извлекается величина "смещения", которая прибавляется к полученному адресу и дает адрес обрабатывавшей процедуры. Этот адрес выставляется на стеке и командой RET (возврат) осуществляется переход по вычисленному адресу процедуры.
0FA0-0FA8 - таблица клавиш редактирования._
Символ |
смещение |
адрес процедуры |
07 EDIT |
09 |
0FA9 |
08 курсор влево |
66 |
1007 |
09 курсор вправо |
6A |
100C |
0A курсор вниз |
50 |
0FF3 |
0B курсор вверх |
B5 |
1059 |
0C DELETE |
70 |
1015 |
0D ENTER |
7E |
1024 |
0E SYMBOL SHIFT |
CF |
1076 |
0F GRAPHICS |
D4 |
107C |
0FA9-0FF2 ED-EDIT
Если Вы находитесь в режиме редактирования, то нажатие клавиши EDIT переводит текущую БЕЙСИК-строку в нижнюю часть экрана для редактирования.
Если Вы находитесь в режиме ввода по INPUT, то нажатие этой клавиши выполняет сброс введенной информации для повторного набора.
В регистровую пару HL вводится содержимое системной переменной E-PPC (23625,23626), т.е. номер текущей БЕЙСИК-строки. Далее, если обрабатывается INPUT-строка (определяется по 5-ому биту FLAGX) - переход на CLEAR-SP (1097) для очистки, а если БЕЙСИК-строка, работа продолжается.
Вызовом LINE-ADRR (1966) вводится начальный адрес этой строки.
Вызовом LINE-NO (1695) по адресу определяется номер строки.
Выполняется проверка номера строки на ноль. Если это так, то следует переход на CLEAR-SP (1097) для очистки области редактирования. (Нулевая строка не редактируется!)
Определяется длина строки и вызовом TEST-ROOM (1F05) выясняется, есть ли место для ее копирования из Бейсик-области в область редактирования.
В регистре HL устанавливается начальный адрес строки, а на стеке - адрес процедуры, обрабатывающей текущий канал ввода-вывода (из системной переменной CURCHL (23633,23634)).
Вызовом CHAN-OPEN (1601) открывается канал "R". В отличие от прочих стандартных каналов "K", "S" и "P", он является внутренним и не связан с внешними периферийными устройствами. Он связывает программную область БЕЙСИКа (где хранится программа) с областью редактирования.
Вызовом OUT-LINE (1855) выполняется "печать" БЕЙСИК-строки. Поскольку открыт канал "K", то эта "печать" представляет из себя ни что иное, как копирование текущей строки из программной области в область редактирования.
Далее выставляется положение курсора - в строке редактирования после ее номера и вызывается CHAN-FLAG (1615), которая восстанавливает предыдущее значение канала ввода/вывода и выставляет в соответствии с ним значения флаговых переменных.
0FF3-1000 ED-DOWN
Если выполняется обработка INPUT-строки - переход на ED-STOP (1001). В противном случае вызовом LN-FETCH (190F) определяется номер следующей строки и переходом на ED-LIST (106E) запускается автоматический листинг.
1001-1006 ED-STOP
В системной переменной ERG NR (23610) выставляется код 10H (что означает STOP IN INPUT) и выполняется переход на ED-ENTER (1024).
1007-100B ED-LEFT
Курсор перемещается влево посредством вызова ED-EDGE (1031). Далее работа продолжается переходом на ED-CHR (1011).
100C-1010 ED-RIGHT
Проверяется текущий символ. Если это CHR13 ("возврат каретки"), то возврат по RET. Если же нет, то увеличивается на единицу адрес положения курсора.
1011-1014 ED-CUR
Адрес курсора запоминается в системной переменной K-CUR (23643,23644) и выполняется возврат по RET.
1015-101D ED-DELETE
Речь идет о стирании символа, находящегося слева от курсора. Курсор передвигается влево вызовом ED-EDGE (1031). Текущий символ удаляется вызовом RECLAIM-2 (19E8).
101E-1023 ED-IGNORE
Процедура вызывается из ED-LOOP (0F38). Двойным вызовом WAIT-KEY (15D4) игнорируются два вводимых кода.
1024-1025 ED-ENTER
Речь идет о завершении ввода строки. Со стека снимаются адреса ED-LOOP (обеспечивающий цикл ввода символов) и ED-ERROR (устанавливающий месторасположение процедуры обработки ошибок, возникающих при редактировании).
1026-1030 ED-END
В системной переменной ERR-SP выставляется исходный адрес процедуры обработки ошибок. Если при редактировании не было ошибок, выполняется возврат в вызывающую программу, а если были, то переход на их обработку.
1031-103D ED-EDGE
Здесь речь идет о перемещении курсора влево. Во внимание должны быть приняты следующие обстоятельства:
- не достигнуто ли уже начало строки;
- не следует выставлять курсор между управляющими кодами и сопровождающими их операндами.
Вызовом SET-DE (1195) инициализируется регистр DE. В нем выставляется адрес системной переменной E-LINE, если идет редактирование БЕЙСИК-строк или адрес WORKSP, если идет обработка команды INPUT.
Сначала проверяется левый край. Если он достигнут - возврат на ED-LOOP (через адрес на стеке).
103E-1050 ED-EDGE-1
Далее обеспечивается неотделение управляющих кодов от их параметров. Вводится код текущего символа. Если это не код от INK до TAB - переход на ED-EDGE-2 (1051). Иначе пропускается один параметр.
1051-1058 ED-EDGE-2
Если есть еще параметры, переход на ED-EDGE-1 (103E), в противном случае возврат.
1059-106D ED-UP
Обслуживается код CHR$ 11 ("курсор вверх").
Если идет обработка INPUT-строки, то этой клавише делать нечего - сразу выполняется возврат. Работа продолжается, если речь идет о строке БЕЙСИК-программы.
Вызовом LINE-ADDR (196E) и далее LINE-NO (1695) определяется номер строки, в которой находился курсор. Вызовом LN-STORE (191C) в системную переменную E-PPC (23625,23626) заносится этот номер.
106E-1075 ED-LIST
Вызовом AUTO-LIST (1795) выполняется перепечатывание листинга на экране. Работа процедуры заканчивается переходом на процедуру, открывающую канал ввода/вывода CHAN-OPEN (1501) при установленном в аккумуляторе номере потока, равном 0, что открывает канал "K".
1076-107B ED-SYMBOL
Сюда мы попадаем, если был нажат SYMBOL SHIFT. Если речь идет о БЕЙСИК строке из программной области, то его быть не должно и переходом на ED-ENTER (1024) выполняется возврат.
Если же речь идет об INPUT-строке, то это какое-то ключевое слово и работа продолжается.
107C-107E ED-GRAPH
Для приема символа (графического или берущегося при нажатой клавише SYMB SHIFT) выполняется переход на ADD-CHAR (0F81).
107A-1096 ED-ERROR
Сюда мы попадаем в случае возникновения какой-либо ошибки при редактировании.
При работе с любым иным каналом, кроме "K" выполняется переход на конец редактирования ED-END (1026). В противном случае вызовом BEEPER (03B5) выдается звуковой сигнал, свидетельствующий об ошибке. Его длительность берется из системной переменной RASP (23606). Далее выполняется переход на ED-AGAIN (0F30).
1097-10A8 CLEAR-SP
Процедура служит для очистки области редактирования, что выполняется вызовом подпрограммы RECLAIM-1 (19E5) после того, как подпрограмма SET-HL (1190) выставит нужным образом регистровые пары HL и DE.
Здесь же устанавливаются в исходное положение системные переменные K-CUR (23643,23644) и MODE (23617).
Подпрограмма "KEYBOARD INPUT".
Эта подпрограмма имеет очень важное значение. Она возвращает в регистре A процессора код каждой нажатой клавиши. Но основное значение этого блока процедур состоит в том, что именно этот блок стандартно привязан к входному каналу "K" (клавиатура), о чем мы будем еще говорить в следующих выпусках.
10AB-10D7 KEY-IBPUT
Сначала проверяется 3-ий бит системной переменной TV-FLAG (23612). Если он включен (включается в WAIT-KEY (15D4)), то это сигнал на копирование строки из области редактирования или из буфера INPUT в нижнюю часть экрана, что и делается вызовом ED-COPY (111D).
По 5-ому биту системной переменной FLAG (23611) определяется, была ли нажата клавиша. Если нет - возврат.
Если была, ее код считывается из системной переменной LAST-K (23560).
По 5-му биту TV-FLAG (23612) устанавливается, подлежит ли переделке нижняя часть экрана. Если да, то это делается вызовом CLS LOWER (0D6E).
Далее работа распределяется по процедурам. Если принятый код является печатным символом - переход на KEY-DONE (111B). Если это управляющий код - переход на KEY-CONTR (10FA).
Если принятый код свидетельствует о включенном режиме CAPS LOCK или несет информацию о режиме, в котором находится клавиатура, выполняется переход на KEY-M&CL (10DB).
Далее обрабатываются коды FLASH, BRIGHT и INVERSE и работа продолжается переходом на KEY-DATA (1105).
10DB-10E5 KEY-M&CL
Не оставляя обработку режима CAPS LOCK процедурам, обслуживающим клавиатуру, здесь при обработке ввода через INPUT выставляются необходимые флаги и выполняется переход на KEY-FLAG (10F4).
10E6-10F3 KEY-MODE
Точно также обрабатывается переключение клавиатуры в другой режим.
10F4-10F9 KEY-FLAG
Заключительные операции по установке флагов и возврат.
10FA-1104 KEY-CONTR
Здесь обрабатываются управляющие коды (кроме FLASH, BRIGHT и INVERSE), т.е. либо INK, либо PAPER. Какой из них конкретно - определяется по тому, была ли нажата при вводе этого кода клавиша SHIFT (no третьему биту кода). И в том и в другом случае переход на KEY-DATA (1105).
1105-110C KEY-DATA
Принятый управляющий код запоминается в системной переменной K-DATA (23565), в регистр DE устанавливается адрес 110D (зачем - будет ясно чуть ниже) и выполняется переход на KEY-CHAN (1113) для смены адреса процедуры, выполнявшей обработку информации, поступавшей из входного канала "K". Там он будет установлен на KEY-NEXT (110D).
110D-1112 KEY-NEXT
Поскольку после управляющего кода должен идти операнд, поэтому и возникла необходимость переключить канал сюда. Здесь этот операнд принимается в аккумулятор и вновь в регистр DE засылается адрес 10A8 (подготовка к восстановлению исходного адреса процедуры, обрабатывающей информацию от канала).
1113-111A KEY-CHAN
Здесь выполняется переключение каналов.
111B-111C KEY-DONE
Финишная процедура. По возвращении из нее флаг CARRY включен, если код от клавиши был успешно принят, а сам этот код находится в аккумуляторе.
Подпрограмма "LOWER SCREEN COPYING"
Эта подпрограмма также представляет из себя пакет процедур. По своему назначению она является вспомогательной и вызывается для работы тогда, когда надо взять редактируемую строку из области редактирования или из буфера INPUT и поместить в нижнюю часть экрана.
111D-1150 ED-COPY
Основная процедура этого блока.
Вызовом TEMPS (0D4D) вводит постоянные цветовые атрибуты.
Устанавливает необходимые флаги.
Запоминает на стеке системные переменные S-POSNL(23690,23691), ERR-SF(23613,24614).
Устанавливает в ERR-SP в качестве адреса процедуры обработки ошибок значение 1167, что соответствует процедуре ED-FULL.
Запоминает на стеке содержимое ECHO-E.
Вызовом SET-HL (1195) инициализирует регистр HL.
Вызовом OUT-LINE2 (187D) печатает строку.
Вызовом OUT-CURS (18E1) печатает курсор.
Вызовом TEMPS (0D4D) вновь вводятся постоянные цветовые атрибуты.
1150-115D ED-BLANK
Если напечатанная строка не равна по длине экранной строке, то это имеет некрасивый вид, поскольку могут различаться по цвету то, что печатается и то, что в этом месте экрана было до печати.
Поэтому необходимо дополнить напечатанную строку до полной посредством печати пробелов в установленном цвете.
Если в этом нет необходимости, то сразу выполняется переход на ED-C-DONE (117C).
Для исполнения печати пробелов - переход на ED-SPACES (115E).
115E-1166 ED-SPACES
Вызовом процедуры PRINT-OUT (09F4) выполняется печать пробела. Далее следует переход на ED-BLANK (1150), что обеспечивает работу в цикле.
1167-117B ED-FULL
Здесь обрабатывается возникшие ошибки. Вызовом BEEPER (03B5) выдается звуковой сигнал с продолжительностью, установленной в системной переменной RASP (23608) и следует переход на финиш ED-C-END (117E).
117C-117D ED-C-DONE
При нормальном завершении работы перед выходом необходимо снять запомненные
на стеке параметры и восстановить их в регистрах процессора, что здесь и делается.
117E - 118F ED-C-END
Восстанавливаются значения системных переменных ERR-SP (23613,24614), ECHO-E (23682, 23663) и др., после чего выполняется возврат в вызывающую процедуру.
Подпрограмма "SET-HL AND SET-DE".
Здесь содержатся всего две вспомогательные процедуры.
1190-1194 SET-HL
В регистровую пару HL засылается содержимое системной переменной WORKSP (23649,23650) минус единица. Т.е. после этого регистр HL указывает на конец рабочего пространства.
1195-11A6 SET-DE
В режиме редактирования здесь в регистровую пару DE устанавливается из системной переменной E-LINE (23641,23642) адрес начала области редактирования и выполняется возврат.
Если Вы не находитесь в режиме редактирования, здесь устанавливается значение взятое из WORKSP (23649,23650).
Подпрограмма REMOVE-FP
Эта подпрограмма имеет сомнительное отношение к процедурам редактора, поскольку в нем нигде не вызывается и наверное осталась в этом блоке процедур по каким-то историческим причинам.
Ее назначение - удалить из БЕЙСИК-строки все числа, записанные в формате с плавающей точкой (в пятибайтной интегральной форме). Кстати, об этом формате Вы можете почитать в нашем трехтомнике, поскольку в рамках материалов "Секреты ПЗУ" мы до этого дойдем еще не скоро.
В двух словах: действительные числа с плавающей точкой хранятся в БЕЙСИК-строках в виде пяти байтов, перед которыми стоит код 0E.
Эта процедура отыскивает такой код в БЕЙСИК-строке и, проходя шесть раз, удаляет шесть ненужных байтов - пять байтов числа и шестой байт - сам код 0E.
Удаление байтов выполняется вызовом процедуры RECLAIM-2 (19E8).
А сейчас мы прощаемся до следующего выпуска, в котором начнем рассматривать наиболее важный раздел ПЗУ - блок исполняющих процедур.