Чтобы успеть к первомаю, пришлось здорово потрудиться восьмибитным мозгом и решить множество мелких проблем, буквально одолев их и победив.
Потому, Вашему вниманию представляется версия текстового редактора с официальным названием:
ПОБЕДИТ
Представляемый текстовый редактор разработан специально на работу в дополнительном ПЗУ F000-F7FF, с аккуратным использованием области служебных ячеек Монитора, чтобы дать пользователю максимальный объём ОЗУ.
Редактор имеет самый минимальный функционал, достаточный для элементарного редактирования текстов. Однако, с помощью пользовательского кода функционал интерфейса редактора можно расширить с помощью CallBack-вызовов. Для этого предоставляется небольшой API.
Список точек вызова основных API:
- F000 - Обычный запуск редактора (директива U Монитора)
- F003 - Запуск редактора с указанием пользовательского кода (в HL)
- F006 - Переключение (с предустановкой) буфера листинга (адрес в HL)
- F009 - Переключение (без предустановки) буфера листинга (адрес в HL)
- F00C - Панорамная прокрутка листинга (CF=0 - вперёд / CF=1 - назад)
- F00F - Вертикальная прокрутка листинга (CF=0 - вперёд / CF=1 - назад)
- F012 - Помещение в стек адреса знакоместа из непосредственных констант
- F018 - Помещение в стек адреса знакоместа по позиции X=E и Y=D
- F01B - Помещение в стек адреса знакоместа (без растровой коррекции)
Однако, рассмотрим основной набор подпрограмм.
CALL F003 - Передача управления редактору с указанием ассистента
Явно передать CallBack-адрес на пользовательский код нужно регистром HL.
При этом, если буфер текста листинга не был предустановлен, директивой X Монитора пользователю предложится это сделать самостоятельно модификацией регистра HL.
CALL F006 - Предустановка буфера листинга
Данную подпрограмму следует вызывать перед передачей управления самому редактору, чтобы через регистр HL установить указатель на основной буфер листинга.
CALL F009 - Переключение буфера листинга
Пользовательский код может переключать текстовый буфер на лету, передавая адрес регистром HL. Необходимости указания на самое начало буфера нет, так как вычисление номера верхней отображаемой строки происходит автоматически.
CALL F00C - Динамическая прокрутка листинга на экране
Для прокрутки текста листинга на 1 символ влево или вправо, через флаг CF указывается направление. При этом подпрограмма возвращает флаг ZF в случае, если прокрутка не возможна по причине достижения начала строки или предела панорамы.
CALL F00F - Динамическая прокрутка листинга на экране
Для прокрутки текста листинга на 1 строку вверх или вниз, через флаг CF указывается направление. При этом подпрограмма возвращает флаг ZF в случае, если прокрутка не возможна по причине достижения начала или конца текста листинга.
CALL F012 - Помещение в стек адреса экранного знакоместа по константным координатам
Подпрограмма достаточно быстро (без цикла) математически вычисляет адрес и возвращает его в стеке. После обращения к подпрограмме, адрес следует извлекать любой командой POP.
Координаты знакоместа следует указать двумя байтами непосредственно за командой CALL.
При этом производится незначительная коррекция по знакоместу, чтобы адаптировать вывод под специфику дисплея.
CALL F018 - Помещение в стек адреса экранного знакоместа по координатам в DE с коррекцией
Подпрограмма достаточно быстро (без цикла) математически вычисляет адрес и возвращает его в стеке. После обращения к подпрограмме, адрес следует извлекать любой командой POP.
Координаты знакоместа следует указать регистрами D (позиция по Y) и E (позиция по X).
При этом производится незначительная коррекция по знакоместу, чтобы адаптировать вывод под специфику дисплея.
CALL F01B - Помещение в стек адреса экранного знакоместа по координатам в DE без коррекции
Подпрограмма достаточно быстро (без цикла) математически вычисляет адрес и возвращает его в стеке. После обращения к подпрограмме, адрес следует извлекать любой командой POP.
Координаты знакоместа следует указать регистрами D (позиция по Y) и E (позиция по X).
Никакой коррекции по знакоместу не производится.
Список критически важных ячеек программы:
- F018-F01A - Три команды для растровой коррекции на ±3 знакоместа (настроить перед прошивкой ПЗУ)
- F040/F041 - Начальные координаты (обычно 8 и 3) курсора (настроить перед прошивкой ПЗУ)
- F4DA-F4DC - Установка флажка подпрограммы опроса клавиатуры (F812), чтобы код пользователя мог прочитать код функциональной клавиши обычным вызовом CALL F803 (читать про флаг ZF ниже)
- F7FE/F7FF - Адрес входа в редактор (просто указывает на расположение основного кода)
- Обычное позиционирование: F018 [00 00 00]; F040 [08 03]
- Смещение на 1 знакоместо: F018 [13 00 00]; F040 [09 03]
- Смещение на 2 знакоместа: F018 [13 13 00]; F040 [0A 03]
- Смещение на 3 знакоместа: F018 [13 13 13]; F040 [0B 03]
- 7629 - Код символа заполнения пространства табуляции
- 762A - Код символа обрамления левого края текстовой области
- 762B - Код символа обрамления правого края текстовой области
- 762D - Маскирование столбца счётчика строк (слева от текста)
- 762E - Корректировочное смещение знакоместа светового пера
- 7633 - Код символа переполнения панорамы
- 7614 (PC директивы X) - CallBack-адрес на пользовательский код
- 7616 (HL директивы X) - Адрес в текстовую область листинга
- 7618 (BC директивы X) - Счётчик строк
- 761A (DE директивы X) - Позиция курсора относительно области текста
- 761C (SP директивы X) - Указатель на начало текущей строки с курсором
- 761E (AF директивы X) - Значение панорамной прокрутки и флаги
- 7634 - Указатель на 25 строк выше (используется для PageUp-операции)
- 7636 - Указатель на 1 строку выше (используется курсорной клавишей)
- 7638-7668 - Массив 25 указателей на каждую из 25 отображённых строк
- 766A - Указатель на 26 скрытую строку (используется PageDown-операцией)
- 766C/766D - Двоично-десятичный номер верхней скрытой строки (используется прокруткой)
- 766E/766F - Двоично-десятичный номер нижней скрытой строки (используется прокруткой)
- HOME с прокрученной панорамой возвращает её на 64 позиций назад или в исходную позицию
- HOME из любой позиции в строке устанавливает курсор в начало строки
- HOME в начале любой строки устанавливает курсор в начало экрана
- HOME в начале экрана прокручивает его на 25 строк вверх (аналогично Page Up)
- END/СТР устанавливает курсор в конец строки со сдвигом панорамы (если строка выходит за пределы)
- END/СТР в конце строки устанавливает курсор в конец экрана
- END/СТР в конце экрана прокручивает его на 25 строк вниз (аналогично Page Down)
- DEL/ПС в любой позиции строки удаляет символ под курсором
- DEL/ПС в конце строки производит слияние со следующей строкой
- BS/ЗАБОЙ в любой позиции строки затирает символ перед курсором
- BS/ЗАБОЙ в начале строки производит слияние с предыдущей строкой
- BS/ЗАБОЙ в начале текста устанавливает курсор в конец первой строки (не смертельный побочный баг, который тяжело устранить без тупой проверки, затрачивающей кучу кода)
При этом через регистры общего назначения передаётся следующая информация:
- BC - Шестнадцатеричный индекс (редактируемой) текущей строки
- DE - Адрес на начало самой верхней отображаемой строки
- HL - Адрес на начало текущей (редактируемой) строки
- A - Номер столбца по позиции курсора (начало - 01) с учётом панорамы (логическая позиция)
- CF флаг - Экран готовится к полной перерисовке (при клике "световым пером" или перемещением стрелками)
- PF флаг - Двойной (повторный) клик "светового пера" по знакоместу с курсором
- ZF флаг - Клавиши F1-F4, АР2 или УС+A-Z (код читается через вызов F803 обязательно, иначе возникнет зацикливание редактора/!\)
- SF флаг - Буферная строка (редактирование в активном состоянии)
Как всегда, вот ссылка на онлайн демонстрацию с кодом для ПЗУ (F000-F7FF) и rkr-файл.
ПРИМЕЧАНИЕ
С адреса F748 располагаются подпрограммы прокрутки экрана с оптимизацией по скорости.
Если их редуцировать и ухудшить производительность (что, на самом деле, не так критично), можно освободить некоторое кодовое пространство под дополнительный функционал, который в оригинальной разработке специально никак не реализовывался.
P.S.: За месяц был проделан практически титанический труд по разработке кода с чистого листа.
Потому, основной код перенесён именно в область F000-F7FF, чтобы всегда под рукой иметь инструмент для личных нужд. В частности, для разработок собственных интерпретаторов языков высокого уровня.
Спасибо за участие!