1 Отредактировано Voldemar0 (11-03-2018 15:09)

Тема: Немного сложный, немного простой текстовый редактор

Привет!

Почти всю жизнь я разговариваю сам с собой. Обычно вслух, если никого нет рядом, хотя случается бурчать себе под нос даже когда рядом кто-то есть. В общем-то, это нужно мне самому - так проще думается. Но иногда, если записать такой монолог и подредактировать его, он может быть интересен многим. Я так думаю. Этакий дневник локального события.

В этой теме я собрал начальные сообщения, связанные с небольшим текстовым редактором от USR. Редактор не был закончен, он разрабатывался под VS-DOS, но мне он интересен тем, что особых глюков в нём нет, есть основные операции редактирования (нет только удаления строк и вставки символов с раздвижкой строки), исходный текст не особенно большой и используемые алгоритмы не очень сложные.

Его можно дописать, но мне бы хотелось привести работу с ним как пример разработки программы под Агат - достаточно понятной и нужной, но, вместе с тем, использующей различные рессурсы машины, такие как видеопамять, работа с большим буфером в ОЗУ, взаимодействие с несколькими операционными системами.

Основная проблема разработки текстового редактора на агате - низкое быстродействие ЦП. Представьте, что у вас есть некий текст. Ну хотя бы 10 кб объёмом. И вам нужно вставить символ в 250ю строку. Если предположить, что каждая строка, например, 20 знаков, то вставка должна произойти примерно в середине файла. Нужно как-то раздвинуть две половины файла (каждая по 5 кб) на один байт. Даже в весьма вылизанном цикле на ассемблере это займёт около полусекунды. Это ещё не много. Но что двигать ? Например, сдвинем вторую часть текста. А теперь нужно вставить символ в начало текста. Вторая часть (от курсора до конца текста) - уже почти 10 кб. Это почти секунда. На каждый вводимый символ. Как быть?

Если бы на агате были ОС и трансляторы, подобные современным, я бы просто ввёл массив указателей на строки текста, затем бы выделил память для каждой строки и при изменении её размеров вызывал диспетчер памяти. Хвост строки ведь короче, чем весь текст, двигать его не сложно. А где и как хранить строки - пусть думает диспетчер памяти. Пусть ведёт таблицы выделенной памяти, думает о стратегиях выделения/освобождения и т.д.

Но всего этого не было на агате в восьмидесятые. Да и до сих пор нет. Типичный способ, используемый с вариациями в данном редакторе, так же как и в редакторе ДОК и в Агат-Авторе: деление текста на две части таким образом, чтобы курсор был близок к границе этого разделения. Начало текста находится в начале буфера, конец текста - в конце буфера:

Начало буфера
   Часть текста 1
   Курсор
   Свободное пространство
   Часть текста 2
Конец буфера

Размер буфера, его начало и конец при этом фиксированы (hardcoded).

При перемещении курсора граница двигается, т.е. небольшой фрагмент из одной верхней
половины буфера перетаскивается в нижнюю или наоборот.
При работе выполяется только две долгих операции (и то - это только из-за ограничений операционных систем): после чтения файла в память вторая часть текста утаскивается в конец буфера, а перед записью возвращается обратно.

Это было краткое введение, а теперь - слайды!

Во вложении следующие файлы:
EDITOR0.txt - авторская версия исходника;
EDITOR1A.txt - моя версия, компилируется точно также как авторская, но имеет комментарии и много символических имён;
EDITOR1B.txt - вторая часть;
usr10e.dsk - образ, с которого можно увидеть работу оригинала (автозагрузка на девятке).

edit2or.zip - моя версия для cc65, там же загрузочный образ (загрузка на семёрке).

Post's attachments

Attachment icon ed1.zip 65.28 kb, 10 downloads since 2018-03-08 

Attachment icon edit2or.zip 53.58 kb, 11 downloads since 2018-03-11 

2 Отредактировано Voldemar0 (12-02-2018 21:24)

Re: Немного сложный, немного простой текстовый редактор

USR пишет:

А вообще, помню году так в 94-м собирался свой ассемблер сделать)) Текстовый редактор сделал под него, кстати.

А может этот редактор портировать на btk и тем приблизить ее к полноценной среде разработки ?

3 Отредактировано USR (13-02-2018 14:35)

Re: Немного сложный, немного простой текстовый редактор

Voldemar0 пишет:
USR пишет:

А вообще, помню году так в 94-м собирался свой ассемблер сделать)) Текстовый редактор сделал под него, кстати.

А может этот редактор портировать на btk и тем приблизить ее к полноценной среде разработки ?

Он был встроен в собственный ДОС..., но вроде есть исходник, надо смотреть... Да и функций там в редакторе минимум. Домой приду-выложу образ. Там прикольно все выглядит, жаль не доделал в свое время.

Что касается ассемблера Школьницы, то вчера впервые увидел сообщение наподобие: "Таблица меток переполнена" ))

Кончился буфер для меток)) Первый раз такое. Это примерно 11,5к строк с некоторыми комментариями. Ну или около 24Кб кода.

UPD. Вот нашел. Диск загрузочный. Свой ДОС. При старте запускается редактор текста. Но он ничего не умеет кроме как символы набирать и строки вставлять. Ну и печатает еще картинку экрана, если принтер в 4-м слоте, по клавише"@". Зато редактор в графике сделан 512х256. И скорость движения текста приличная. Подозреваю, там алгоритм вывода текста оптимизирован. Исходники где-то были вроде, надо искать. Но там явно завязки на функции ДОСа своего...
"Ред"-выход в ДОС, уже в текстовый режим. Команда "list"  выводит список команд ДОС.
Все это не доделано, но вот такое вот было. Это где-то 92-94гг, не позже.
Извиняюсь что офтопик.

4 Отредактировано Voldemar0 (14-02-2018 19:06)

Re: Немного сложный, немного простой текстовый редактор

USR пишет:

Он был встроен в собственный ДОС..., но вроде есть исходник, надо смотреть... Да и функций там в редакторе минимум. Домой приду-выложу образ. Там прикольно все выглядит, жаль не доделал в свое время.

UPD. Вот нашел. Диск загрузочный. Свой ДОС. При старте запускается редактор текста. Но он ничего не умеет кроме как символы набирать и строки вставлять. Ну и печатает еще картинку экрана, если принтер в 4-м слоте, по клавише"@". Зато редактор в графике сделан 512х256. И скорость движения текста приличная. Подозреваю, там алгоритм вывода текста оптимизирован.

Когда ясно, что искать - всё происходит быстро. Думаю, это он:

....
TFД1 JMP($400)
AS3 ASC"f1Oкнa f7Teкcт f8Пoиcк f=Пaлитpa f0Key F1Cтpoкa F2Буфep ESCBыxoд"                             
AS4 DFB$0,7,$F,$17,$21,$27,$30,$38
AS2 ASC"Peдaктop  Acceмблep  Oтлaдчик  VSDOS  Пpинтep  Пoмoщь  Bыxoд"
TEXT JMP($3C0)
....

Только - честно - не понял: зачем там столько абсолютных адресов?

...
 DEC$9F
 BNE REO2
REO1 LDA$A1
 CMP$99
 BNE REO3
 LDA$A2
 CMP$9A
 BNE REO3
 JSR BELL
 JMP RED
REO3 JSR REI
 LDA$75
 STA$90
REO6 JSR RE32
 CMP#$8D
...

А вот это, я полагаю, и есть завязки на VC-DOS:

TEXT JMP($3C0)
TEXTF JMP($30A)
TEXTR JMP($3A6)
TEXTH JMP($310)
BELL JMP($31C)
TEXT6 JMP($304)
TEXTU JMP($3A8)
TEXTB JMP($302)
KEYA JMP($36E)
TEXTV JMP($3AA)
TFTЫ JMP($460)
TEXTRR JMP($3BE)
FPD JMP($3BC)
ED LDA#$00
 JMP($36A)

5

Re: Немного сложный, немного простой текстовый редактор

Voldemar0 пишет:

Когда ясно, что искать - всё происходит быстро. Думаю, это он:

Только - честно - не понял: зачем там столько абсолютных адресов?

Похоже что он))

Что значит абсолютных адресов? Вот эти вот ячейки что-ли? $99, $9A, $A2?

Ну там данные какие-то хранятся... размер окна и т.п.

6 Отредактировано Voldemar0 (15-02-2018 04:51)

Re: Немного сложный, немного простой текстовый редактор

USR пишет:

Что значит абсолютных адресов? Вот эти вот ячейки что-ли? $99, $9A, $A2?

Ну там данные какие-то хранятся... размер окна и т.п.

Я имею ввиду : почему не символические имена ?
LDA WIN_W
LDX WIN_H

7

Re: Немного сложный, немного простой текстовый редактор

Voldemar0 пишет:

Я имею ввиду : почему не символические имена ?
LDA WIN_W
LDX WIN_H


А! ну это мой дурной стиль. Видимо было лень пару лишних символов набирать))

8

Re: Немного сложный, немного простой текстовый редактор

USR пишет:

А! ну это мой дурной стиль. Видимо было лень пару лишних символов набирать))

Стиль - стилем, но столько цифр помнить ....... :)
Для меня в школе самые нелюбимые занятия были: учить стихи наизусть и бегать по спортзалу :)

9 Отредактировано Voldemar0 (03-03-2018 21:49)

Re: Немного сложный, немного простой текстовый редактор

USR пишет:

UPD. Вот нашел. Диск загрузочный. Свой ДОС. При старте запускается редактор текста. Но он ничего не умеет кроме как символы набирать и строки вставлять. Ну и печатает еще картинку экрана, если принтер в 4-м слоте, по клавише"@". Зато редактор в графике сделан 512х256. И скорость движения текста приличная. Подозреваю, там алгоритм вывода текста оптимизирован. Исходники где-то были вроде, надо искать. Но там явно завязки на функции ДОСа своего...

Прошерстил уже больше половины, очень напоминает редактор ДОК, в смысле такое же деление буфера на две части. Но у ДОК деление буфера происходило кратно строке, а тут, похоже, по текущему символу.

Скорость в графике приличная потому что кое что оптимизировано: например, при скролинге экрана перевыводятся/перемещаются только изменившиеся символы. Фактически, все операции идут в скрытом текстовом режиме, в графику только зеркалируются изменения. Кроме того: там же только окно - оно меньше половины экрана. Развернуть его на полный экран - будет медленнее.

Исходник не очень тяжелый для понимания, после разбора линкера почти халява.

Я не буду пока его улучшать, только хочу разобрать, прокомментировать, заменить численные константы на символьные. Потом проверю на совпадение результатов компиляции (исходной и моей версии).

Затем уберу поддержку графики, чтобы чуть упростить и попробую перетащить под cc65 с возможностью сборки под ИКП-Бейсик и ДОК. Будет нормальная такая демка для cc65.

(
Когда-то мне очень хотелось написать свой (или адаптировать из ДОК) редактор текста, сразу под бейсик-60. Даже начал над этим работать, старался приблизить редактор ДОК к чему-то вроде редакторов борландовских IDE. Чтобы была и вставка символов по умолчанию и прочие плюшки. Однако закончить эту работу не успел.

Но после разбора кучи коллекций интерес пропал - мы нашли много новых редакторов текста для Агата, хотя я и не копался до сих пор в них.
)

10 Отредактировано USR (04-03-2018 01:14)

Re: Немного сложный, немного простой текстовый редактор

Voldemar0 пишет:

Прошерстил уже больше половины, очень напоминает редактор ДОК, в смысле такое же деление буфера на две части. Но у ДОК деление буфера происходило кратно строке, а тут, похоже, по текущему символу.

Ну... да, я  помню, подсмотрел как сделано в ДОКе. Даже не смотрел код ДОКа, просто по тому как текст в памяти располагается посмотрел и все сделал похоже. Деление буфера точно по текущему символу. Это 100%. Странно что нет режима вставки символа, удаления строк...

Voldemar0 пишет:

Скорость в графике приличная потому что кое что оптимизировано: например, при скролинге экрана перевыводятся/перемещаются только изменившиеся символы.

Да, это я придумал еще в школе. В принципе, алгоритм то на поверхности лежит. Сдвигать только то, что необходимо. В играх аналогично делал. Яга-2, и все игрушки под Топаз.

Voldemar0 пишет:

Исходник не очень тяжелый для понимания, после разбора линкера почти халява.

Да? А я вот особо сам себя понять не могу))

Voldemar0 пишет:

Затем уберу поддержку графики, чтобы чуть упростить и попробую перетащить под cc65 с возможностью сборки под ИКП-Бейсик и ДОК. Будет нормальная такая демка для cc65.

Отлично! С графикой там такое дело. Разрабатывался свой ДОС. В том числе там кроме работы с дисками и файлами, были функции рисования окна, вывода строки, символа и т.п.
Это файлы-исходники, USR(чуток битый, но можно восстановить, мы уже обсуждали это), US, YS.

В начале каждой функции в этом ДОСе, или как его назвать, стоит:

; начало функции
         JMP(xxxx)
yyyЫ ...

По умолчанию, по адресу хххх лежит адрес yyyЫ. Так вот подразумевалось, что если будет графика, то достаточно загрузить резидента, который перехватит вывод символа на экран, т.е. запишет по адресу хххх адрес своей функции вывода граф. символа. Вот в этом редакторе похоже такой перехват (и не один) используется.

Т.е. если графику отключить, надо функцию вывода символа добавить...  Наверное)))) Ну и еще там функции какие-то из ДОСа этого используются.

ЗЫ. Вполне возможно, что в этом редакторе ошибки есть)) Не то чтобы я как попало это все писал, но не помню, тестировал ли эту программу.

11 Отредактировано Voldemar0 (04-03-2018 08:08)

Re: Немного сложный, немного простой текстовый редактор

> Да? А я вот особо сам себя понять не могу))

У современных текстовых редакторов есть чудесная функция: поиск с заменой. Особенно если есть поддержка регулярных выражений. Это позволяет такой кусок:

 LDA#>TFЙ
 STA$360
 LDA#<TFЙ
 STA$361
 LDA#>TF4
 STA$328
 LDA#<TF4
 STA$329
 LDA#>TFД
 STA$300
 LDA#<TFД
 STA$301

довольно быстро превращать в такой:

; Задаём собственные callback-функции к досовским операциям

 LDA #>MY_PUTCHAR
 STA DOS_H_PUTCHAR+0
 LDA #<MY_PUTCHAR
 STA DOS_H_PUTCHAR+1

 LDA #>MY_SCROLL_WIN
 STA DOS_H_SCROLL_WIN+0
 LDA #<MY_SCROLL_WIN
 STA DOS_H_SCROLL_WIN+1

 LDA #>MY_SET_VIDEO_MODE
 STA DOS_H_SET_VIDEO_MODE+0
 LDA #<MY_SET_VIDEO_MODE
 STA DOS_H_SET_VIDEO_MODE+1

становится всё гораздо яснее.

Сейчас часть текста у меня выглядит примерно так:

REЭ4
 JSR REM41
 LDY #$00
 LDA ($A1),Y
 JSR REM4
 CMP #CHAR_CR
 BEQ REЭ55
 CLC
REЭ55
 JSR REZ
REЭ54
 LDA DOS_DRAW_X1
 STA ED_PH_COL
REЭ5
 LDX ED_PH_COL
 LDY ED_PH_LINE
 JSR DOS_VT_CALC
REЭ12

- тут кое что уже распознано, но ещё пока не всё.

Парочка вопросов:

1) В коде есть процедуры вывода текста в графике, но нет чтения шрифта. Хотя в памяти он уже есть. Т.е. как бы получается, что ДОС читает шрифт сама, но не имеет операций с графическим режимом. Почему ? В autoexec команд чтения отдельных файлов шрифта тоже нет, да и самих файлов я не вижу. Или сам редактор собран со шрифтом встроенным?

2) Часть ДОС-векторов лежит в регионе $3xx и ещё часть в $4xx. Как я понял, регион 3 - это просто вектора на функции ДОС. А вот 4 - это вроде как хуки для встраивания своих callback-функий (Т.е. мы вызываем, например, функцию вывода символа. ДОС выводит символ в текстовое окно, а потом вызывает зарегистрированную нами (callback) функцию, в которой мы выводим тот же символ уже в графике) ? Или такого деления нет ? В то же время есть операция копирования региона 4 на 3 перед выходом из редактора. Она совсем сбила меня с толку.

12

Re: Немного сложный, немного простой текстовый редактор

Voldemar0 пишет:

Парочка вопросов:

1) В коде есть процедуры вывода текста в графике, но нет чтения шрифта. Хотя в памяти он уже есть. Т.е. как бы получается, что ДОС читает шрифт сама, но не имеет операций с графическим режимом. Почему ? В autoexec команд чтения отдельных файлов шрифта тоже нет, да и самих файлов я не вижу. Или сам редактор собран со шрифтом встроенным?

Задумывалось конечно, чтобы шрифты были подгружаемыми. Но файлов со шрифтами еще не было сделано. Вся разработка остановилась как раз вот на этом редакторе. Видимо, чтобы попробовать графику, я сделал загрузку шрифта при загрузке самого ДОС. т.е. шрифт лежит в памяти изначально, еще до запуска autoexec.


Voldemar0 пишет:

2) Часть ДОС-векторов лежит в регионе $3xx и ещё часть в $4xx. Как я понял, регион 3 - это просто вектора на функции ДОС. А вот 4 - это вроде как хуки для встраивания своих callback-функий (Т.е. мы вызываем, например, функцию вывода символа. ДОС выводит символ в текстовое окно, а потом вызывает зарегистрированную нами (callback) функцию, в которой мы выводим тот же символ уже в графике) ? Или такого деления нет ? В то же время есть операция копирования региона 4 на 3 перед выходом из редактора. Она совсем сбила меня с толку.

Думаю работает так. В регионах $3xx и $4xx изначально одно и тоже.
В $4xx просто копия. Запись по адресам $300-$301 позволяет миновать функцию ДОС и вызвать свою. Если все же эта функция ДОС тоже нужна, она доступна по адресам $400-$401.
При завершении работы редактора, все восстанавливается как было, поэтому и копирование 4хх в 3хх. Сам ДОС вызывает функции свои по региону $3xx. Видимо так сделано, чтобы не запоминать какие адреса меняли... А может что-то планировалось, на случай если перехватчиков будет несколько...
В любом раскладе в регионе $4xx векторы на "родные" функции ДОС.
--------------------
Вроде  часть функций ДОС имеет такие вызовы не только в своем начале, но и в конце. Например:

  JMP($310)
Ы1
; функция ДОС
  JMP($312)
Ы2 RTS

В $310-$311 адрес метки Ы1, а в $312-$313 адрес метки Ы2. Т.е. можно перехватить функцию ДОС до ее выполнения, а можно и после.

13 Отредактировано Voldemar0 (04-03-2018 18:33)

Re: Немного сложный, немного простой текстовый редактор

У тебя архитектура редактора примерно такая: на каждую пользовательскую операцию (стрелки, клавиша ВВОД, ввод символа), выполняется своя, довольно непростая, процедура. Проверяется возможность выполнить действие, если это возможно, то начинается сложное перестроение внутренних структур (номера строк, указатель на текст в начале экрана, указатели на границы буферов и т.д.).

Почему не было сделано по другому: ведь, например, стрелка - это смена координаты курсора. X++, X--, Y++, Y--. Ну максимум, можно проверить границы - первая или последняя строка сейчас (для Y). Для X достаточно сравнить с границами окна. ВВОД - вставка строки плюс X=0, Y++.

А дальше одна общая процедура, которая, в соответствии с X/Y перестраивает (согласует) остальные внутренние структуры. Например, пересчитывает верхнюю экранную строку, перевыводит экран, если надо.

Сейчас, чтобы, например, добавить листание PgUp/PgDown (не, тут у тебя предусмотрен скрол на несколько строк) или переход на заданную строку (поиск, например) нужно написать ещё кучу процедур.

Был ли такой выбор обусловлен оценкой скорости, например ?

То есть я хочу сказать: разрабатывая программу ведь удобнее думать (и кодировать) отдельно архитектуру интерфейса с пользователем, и только потом уже отдельно думать (и тоже кодировать) логику управления внутренними структурами (т.е. не видимых пользователем).

14

Re: Немного сложный, немного простой текстовый редактор

Voldemar0 пишет:

А дальше одна общая процедура, которая, в соответствии с X/Y перестраивает (согласует) остальные внутренние структуры. Например, пересчитывает верхнюю экранную строку, перевыводит экран, если надо.

Был ли такой выбор обусловлен оценкой скорости, например ?

Проблема в том, что я не помню вообще, как его делал)) Когда делал топаз, там все было просто, там любая строка 16 символов)) А тут могло быть так, сдал сессию, отметил с друзьями, пришел домой и стал писать редактор)). К утру готово.

Да и мне кажется, одну общую универсальную процедуру не очень то просто написать. Видимо мне легче и быстрее было на каждое событие свою процедуру запускать.

Ну и привычка из игр конечно, экономить скорость где только можно. Я же игрушки делал все время...
И вообще мне кажется, что этот редактор больше делался с целью оценить какая в итоге получится скорость в графике. т.е. стоит ли вообще с графикой и шрифтами заморачиваться.

У меня и сейчас в новоделе, тоже редактор и тоже нет универсальной процедуры. Это минус конечно.

15

Re: Немного сложный, немного простой текстовый редактор

Voldemar0 пишет:

Нужно как-то раздвинуть две половины файла (каждая по 5 кб) на один байт. Даже в весьма вылизанном цикле на ассемблере это займёт около полусекунды. Это ещё не много. Но что двигать ? Например, сдвинем вторую часть текста. А теперь нужно вставить символ в начало текста. Вторая часть (от курсора до конца текста) - уже почти 10 кб. Это почти секунда. На каждый вводимый символ. Как быть?

Да ладно!

Loop:
 lda (zp1),y
 sta (zp2),y
 iny
 bne Loop

Это 16 тактов на байт, а значит 64КБ в секунду.

Турбо АГАТ-9/16 (65C802 CPU, 2.8 Маха), MSX2 Yamaha YIS503IIIR.

16

Re: Немного сложный, немного простой текстовый редактор

Я и пишу "около". Суть-то не меняется: если 64 к/сек, то 6 кб (всего 24 блока) - это 10 знаков в секунду максимум. Это уже очень заметное торможение.

17 Отредактировано Voldemar0 (07-03-2018 15:33)

Re: Немного сложный, немного простой текстовый редактор

Сегодня вспомнил одну штуку: в 90-е пользовался попеременно то Агат-Автором, то редактором ДОК. У ДОК было одно занятное преимущество: когда нажимаешь стрелку и ПВТ, курсор бежит и его отчётливо видно. В Агат-авторе же курсор пропадал. Т.е. если кнопки отпустить он появлялся в новом месте, но было непросто угадать, где именно он появится.

Сейчас проверил в эмуляторе: оказалось, Агат-Автор при любом действии, даже перемещении курсора, полностью перерисовывает экран. Получается, что код новой клавиши поступает до вызова процедуры чтения символа с клавиатуры и курсор может даже не быть отрисован (или сразу же стирается). Поэтому его не видно на быстрых повторах. А ДОК же перерисовка экрана происходит только если меняется изображение: при вставке символа перерисовывается только текущая строка, при ВВОД - весь экран. Соответственно, при быстром движении курсора он успевает присутствовать на экране до поступления очередного кода клавиатуры.

Это к слову об оптимизации кода.

18

Re: Немного сложный, немного простой текстовый редактор

LeoN пишет:

Это 16 тактов на байт, а значит 64КБ в секунду.

Да при любой скорости копирования, если есть возможность не двигать 10Кб на каждый чих, то лучше не двигать :)
Как минимум, ничего не двигать, пока редактирование строки не закончится.

Дальше уже возможны варианты. Можно держать текст одним блоком, а текущую строку редактировать в отдельном буфере. Это даст быстрое перемещение курсора, но правка текста в начале буфера будет притормаживать.
А вот в алгоритме с делением буфера пополам вообще не нужно ничего двигать при правке текста в любой части буфера. Все перемещения происходят только при вертикальном движении курсора. Но зато должен хорошо тормозить переход из начала в конец буфера, если текста много.

19

Re: Немного сложный, немного простой текстовый редактор

> Да при любой скорости копирования, если есть возможность не двигать 10Кб на каждый чих, то лучше не двигать :)

Алгоритмы усложняются. Тут балланс желателен.

20

Re: Немного сложный, немного простой текстовый редактор

Чего не люблю, так это писать текстовые редакторы. Поэтому они у меня все кривые.

Как по мне, единственный выход для Агата, это делить буфер на две части. Иначе возможны ситуации, когда будут случаться жуткие тормоза.

Например, нажали ентер. Мало того что надо буфер раздвинуть, так еще и минимум часть экрана перерисовать. Нормально так притормаживает, поверьте мне. Ни разу не айс.

Сделать буфер для редактируемой строки я тоже думал в свое время. Не, как по мне, не катит. Все равно придется потом ее вставлять. И если тормоза будут случаться хотя бы раз в 20 нажатий на клавиатуре, это уже будет раздражать.

Я не супер программист, но мне кажется, для разделенного буфера можно написать хороший редактор.

У меня есть новодел. В соседней ветке кажись выкладывал образ.

Там буфер текста 24КБ. Если загрузить файл TEST, буфер заполнится на 100%. Там можно и строки удалять и режим вставки есть. Если надо, выложу исходник. Где-то 1000 строк...

21 Отредактировано Voldemar0 (08-03-2018 13:14)

Re: Немного сложный, немного простой текстовый редактор

USR пишет:

Где-то 1000 строк...

В этом редакторе около 2000 строк. За счёт чего удалось так оптимизировать? Его код связан с тем, что мы рассматриваем в этой ветке? Как-то можно их назвать по именам или номерам, чтобы не путаться при обсуждении?


Кажется, нашлась одна серьёзная ошибка или недоделка:

редактор располагается в памяти где-то в адресах $4000.49ff, а его буфер (заданный, похоже, операционной системой) - в адресах $2800.BEEE.

22 Отредактировано Voldemar0 (08-03-2018 13:35)

Re: Немного сложный, немного простой текстовый редактор

Первый этап закончил: сейчас у меня есть два текста: авторский и точно такой же по коду, но оборудованный комментариями и символическими именами. Собираются совершенно идентично. Таким образом я могу быть весьма уверен, что этот этап прошел верно. Файлы буду выкладывать и обновлять в виде аттача к первому сообщению темы. Ну и в качестве оформления : скриншот процесса и самого редактора, как он есть сейчас.

Следующим этапом будет перевод исходника для компиляции в ca65 и небольшая косметическая правка (в основном, перестановка процедур таким образом, чтобы собрать единое по смыслу в одну кучу).

Post's attachments

scr.png, 21.89 kb, 790 x 600
scr.png 21.89 kb, 8 downloads since 2018-03-08 

scr2.png, 29.01 kb, 790 x 602
scr2.png 29.01 kb, 11 downloads since 2018-03-08 

23 Отредактировано Voldemar0 (08-03-2018 15:13)

Re: Немного сложный, немного простой текстовый редактор

О программной архитектуре редактора.
Весь код крутится вокруг следующих глобальных переменных:

ED_P_HI_CUR EQU $5C ..$5D  Указатель на текущий символ в верхней части буфера
ED_P_LO_CUR EQU $5E ..$5F  Указатель на текущий символ в нижней части буфера

ED_PH_COL   EQU $75        Физическая (экранная) колонка курсора
ED_PH_LINE  EQU $76        Физическая (экранная) строка курсора

ED_P_LO_BUF EQU $97 ..$98  Указатель на начало текстового буфера
ED_P_HI_BUF EQU $99 ..$9A  Указатель на конец текстового буфера

ED_P_TOP_LN EQU $91 ..$92  Указатель на строку, выводимую в первой физической строке экрана                         

ED_NT_LN_DC EQU $9B ..$9C  Номер строки, выводимой в первой физической строке экрана (в десятичном представлении)
ED_NLINE_DC EQU $9D ..$9E  Номер текущей строки в десятичном представлении

Переменные ED_P_*_CUR задаются до запуска программы операционной системой - это указатели на доступную память. В самом начале редактора их значения копируются в ED_P_*_BUF, а в начале и конце буфера записываются символы перевода строк - они нужны для корректной работы алгоритмов поиска разделителей строк.

Также важны ещё четыре значения:

; Эти ячейки описывают графическое окно для функий ОС, в дальнейшем редактор использует их в этом же значении
DOS_WIND_X1 EQU $7A
DOS_WIND_Y1 EQU $7B
DOS_WIND_X2 EQU $7C
DOS_WIND_Y2 EQU $7D
; В нынешней версии их значения - константы, но код относится к ним как к переменным. Т.е. размер и положение окна редактора можно менять (однако это не отлаживалось и не будет работать идеально).
; Важно: номера строк выводятся левее X1. Т.е. эти границы определяют именно вывод редактируемого текста !

Перечисленные выше ячейки хранятся постоянно, редактор во всех операциях исходит из их значений. Почти все остальные переменные будут вычислятся из них.

Буфер текста делится на две части: P_LO_BUF .. P_LO_CUR и P_HI_CUR .. P_HI_BUF.
Любое движение курсора приводит к сдвигу границ P_LO_CUR и P_HI_CUR. Если они смыкаются (это проверяется при любых операциях вставки) редактор выводит сообщение "Ошибка".

Код построен так, что каждая операция (нажатие стрелок, клавиши ВВОД, ввод символов) выполняет только минимально необходимые операции. Фактически, каждая клавиша имеет свой обработчик, который выполняет только те проверки и перемещения байт, которые необходимы здесь и сейчас. Здесь мало общих процедур, почти весь код обработчиков линеен. Отдельные крупные процедуры (используемые всеми обработчиками):

SCROLL_UP_AND_OUT_SCREEN - прокрутка экрана вверх на заданное в X число физических строк.
SCROLL_DN_AND_OUT_SCREEN - прокрутка экрана вверх на заданное в X число физических строк.
OUT_FULL_SCREEN - обновление всего экрана.
OUT_REST_OF_SCREEN - обновление экрана от курсора и ниже.

Чтобы не путаться:
логическая строка - минимальная последовательность символов в текстовом файле, ограниченная символами "перевод строки".
физическая (экранная) строка - последовательность символов, находящихся на одной высоте изображения на экране.

По агатовской традиции, если логическая строка не помещается в физическую, её делят на несколько физических строк (Есть и другая традиция: выводить только часть логической строки в физическую, таким образом избегая переноса. На агате почему-то не использовалась, хотя для текстов программ это было бы правильнее).

Существенную часть кода редактора занимает именно расчёт соответствий физических строк логическим и наоборот.

Отдельную сложность добавляет особый режим перемещения курсора - полностью свободный ("ДОК-стиль"). Т.е. вы можете двигать курсор в любое место экрана, даже если символов там нет (за знаком "перевод строки"). В этом случае редактор создаёт "виртуальные" пробелы - они не существуют в тексте до тех пор, пока вы не введёте любой символ. При этом виртуальные пробелы становятся реальными, за ними будет следовать и введённый символ.
Если же просто увести (стрелками) курсор с данной строки, виртуальные пробелы из неё исчезают.

ED_VIRT_SPC EQU $90        Количество позиций, на которые курсор правее последнего символа (где как бы нет символов)

О переменных *DC. Эти переменные, хотя и вычисляются редактором при различных операциях, не используется нигде иначе чем для вывода на экран. Они хранятся как шестнадцатерично-десятичные, таким образом максимальный номер строки - 9999. Однако, так как само значение редактору не важно, он может работать и с большим числом строк и за номером 9999 вы увидите на экране строку 0.

Поддержка графики и печать экрана на принтер выполнены как бы немного сбоку от основного кода - они используют свои переменные (довольно далеко от регионов основных переменных). Кроме того, поддержка графики реализована в виде callback функций ДОС: т.е. редактор обращается для ввода / вывода к операционной системе, а она, выполнив операции в текстовом окне, вызывает процедуры редактора, которые дублируют вывод в графическом окне (на это время переключаются модули памяти).

24 Отредактировано USR (08-03-2018 14:46)

Re: Немного сложный, немного простой текстовый редактор

Voldemar0 пишет:
USR пишет:

Где-то 1000 строк...

В этом редакторе около 2000 строк. За счёт чего удалось так оптимизировать? Его код связан с тем, что мы рассматриваем в этой ветке? Как-то можно их назвать по именам или номерам, чтобы не путаться при обсуждении?


Кажется, нашлась одна серьёзная ошибка или недоделка:

редактор располагается в памяти где-то в адресах $4000.49ff, а его буфер (заданный, похоже, операционной системой) - в адресах $2800.BEEE.

Новый-NEW)) В принципе алгоритм такой же наверное)), но я старался экономить память (сейчас размер бинарника $92b), наверное где-то в ущерб скорости. Он еще сырой, одну ошибку недавно только нашел. На счет 1000 строк. На самом деле наверное чуть больше, он же интегрирован в Топаз-2, часть подпрограмм (общих еще с кем-то) лежит в другой области. Но все равно, вместе с вызовом справки, никак не более 1500 строк. В нем мне не хватает функции копирования части текста. А делать лень))

В приложении исходники Топаза2 на сей момент. Файл TEXT это текстовый редактор. Начальный файл ZLOAD, там все начальные установки. В файле MAIN общие функции. Файл  LDOS запись/чтение файлов. HDOS работа с файлами. Исключая запись/чтение, Текстовый редактор-NEW вроде никуда кроме файла MAIN обращаться больше не должен.

Ах, да. NEW для режима TEXT32, т.е. цветной. И метки красным цветом выделяются...

Старый текстовый редактор OLD. То что он по адресам $4000 лежит, прямо посередь буфера это нормально. Это не законченная программа и видимо на тот момент я еще не думал, как распределять память. Ну а чтобы попробовать-задал такой адрес. Мог и $6000 задать))

Post's attachments

Attachment icon Topaz2.DSK 840 kb, 13 downloads since 2018-03-08 

25 Отредактировано Voldemar0 (08-03-2018 15:49)

Re: Немного сложный, немного простой текстовый редактор

> Topaz2.DSK 840 kb

Исходники NEW на диске с ИКП. Но собрать в ДОК не получилось - ошибки валит. Массово. Сборку начинал  с MAIN.