Тема: Немного сложный, немного простой текстовый редактор
Привет!
Почти всю жизнь я разговариваю сам с собой. Обычно вслух, если никого нет рядом, хотя случается бурчать себе под нос даже когда рядом кто-то есть. В общем-то, это нужно мне самому - так проще думается. Но иногда, если записать такой монолог и подредактировать его, он может быть интересен многим. Я так думаю. Этакий дневник локального события.
В этой теме я собрал начальные сообщения, связанные с небольшим текстовым редактором от USR. Редактор не был закончен, он разрабатывался под VS-DOS, но мне он интересен тем, что особых глюков в нём нет, есть основные операции редактирования (нет только удаления строк и вставки символов с раздвижкой строки), исходный текст не особенно большой и используемые алгоритмы не очень сложные.
Его можно дописать, но мне бы хотелось привести работу с ним как пример разработки программы под Агат - достаточно понятной и нужной, но, вместе с тем, использующей различные рессурсы машины, такие как видеопамять, работа с большим буфером в ОЗУ, взаимодействие с несколькими операционными системами.
Основная проблема разработки текстового редактора на агате - низкое быстродействие ЦП. Представьте, что у вас есть некий текст. Ну хотя бы 10 кб объёмом. И вам нужно вставить символ в 250ю строку. Если предположить, что каждая строка, например, 20 знаков, то вставка должна произойти примерно в середине файла. Нужно как-то раздвинуть две половины файла (каждая по 5 кб) на один байт. Даже в весьма вылизанном цикле на ассемблере это займёт около полусекунды. Это ещё не много. Но что двигать ? Например, сдвинем вторую часть текста. А теперь нужно вставить символ в начало текста. Вторая часть (от курсора до конца текста) - уже почти 10 кб. Это почти секунда. На каждый вводимый символ. Как быть?
Если бы на агате были ОС и трансляторы, подобные современным, я бы просто ввёл массив указателей на строки текста, затем бы выделил память для каждой строки и при изменении её размеров вызывал диспетчер памяти. Хвост строки ведь короче, чем весь текст, двигать его не сложно. А где и как хранить строки - пусть думает диспетчер памяти. Пусть ведёт таблицы выделенной памяти, думает о стратегиях выделения/освобождения и т.д.
Но всего этого не было на агате в восьмидесятые. Да и до сих пор нет. Типичный способ, используемый с вариациями в данном редакторе, так же как и в редакторе ДОК и в Агат-Авторе: деление текста на две части таким образом, чтобы курсор был близок к границе этого разделения. Начало текста находится в начале буфера, конец текста - в конце буфера:
Начало буфера
Часть текста 1
Курсор
Свободное пространство
Часть текста 2
Конец буфера
Размер буфера, его начало и конец при этом фиксированы (hardcoded).
При перемещении курсора граница двигается, т.е. небольшой фрагмент из одной верхней
половины буфера перетаскивается в нижнюю или наоборот.
При работе выполяется только две долгих операции (и то - это только из-за ограничений операционных систем): после чтения файла в память вторая часть текста утаскивается в конец буфера, а перед записью возвращается обратно.
Это было краткое введение, а теперь - слайды!
Во вложении следующие файлы:
EDITOR0.txt - авторская версия исходника;
EDITOR1A.txt - моя версия, компилируется точно также как авторская, но имеет комментарии и много символических имён;
EDITOR1B.txt - вторая часть;
usr10e.dsk - образ, с которого можно увидеть работу оригинала (автозагрузка на девятке).
edit2or.zip - моя версия для cc65, там же загрузочный образ (загрузка на семёрке).