Indrekis
Indrekis

Categories

  • retrocomputing
  • cpm
  • CP/M

Tags

  • CP/M
  • retrocomputing
  • te

te

Важливий інструмент для ‘‘реконструкторських’’ експериментів – текстовий редактор. Працювати з ED.COM я поки не готовий. Хоча редагувати файли із кодом можна в WordStar – кажуть, у свій час його для того і використовували, мені не дуже сподобалося – він громіздкий. Пошуки виявили сучасну альтернативу – текстовий редактор te для CP/M, від MiguelVis – великого ентузіаста CP/M.

Забігаючи наперед, завантажити варіант для Osborne-ів можна зі мого форку репозиторію te – файли TE_OSBE.* для Executive та TE_OSB1.* для першого варіанту. Сподіваюся, потрапить і в апстрім – pull-request в процесі обговорення.

Портування te під Osborne Executive

Безпосередньо te не підтримував Osborne Executive. Найближчим виявився варіант для Kaypro II і схожих – te_kp.*. Однак, був неприємний баг – старий текст залишався на екрані там, де не замінявся новим. Як вже зараз знаю – Escape-послідовність ‘‘стерти до кінця рядка’’ в Kaypro не сумісна.

Структура адаптування до нових платформ в te цікава1. Для Kaypro-адаптації, головний файл te_kp.c. Він включає te.c – головний файл реалізації, який вже включає все решта. Код організований так, що є єдиною одиницею трансляції – ніякого лінкування.

Базово, для адаптації потрібно змінювати лише ‘‘драйвер’’, типу te_kp.c – з якого я й розпочав, скопіювавши у te_osbe.c.

Він, грубо, складається із двох частин. Перша частина – конфігурація:

#define CRT_DEF_ROWS 24
#define CRT_DEF_COLS 80

/* ....... skipped .......... */

#define OPT_LWORD 0  /* Go to word on the left */
#define OPT_RWORD 0  /* Go to word on the right */
#define OPT_FIND  1  /* Find string */
#define OPT_GOTO  1  /* Go to line # */
#define OPT_BLOCK 1  /* Block selection */
#define OPT_MACRO 1  /* Enable macros */

Друга – реалізація типових операцій, на які покладається решту коду.

CrtReset() -- використовується під час виходу з te
CrtClear() -- очистити екран і розташувати курсор в (0, 0)
CrtLocate(row, col) -- перемістити курсор
CrtClearLine(row) -- очистити рядок і розташувати курсор в (row,0)
CrtClearEol() -- очистити до кінця рядку 
CrtReverse(on) -- ввімкнути/вимкнути інвертоване відео

Для керування дисплеєм, порт для Kaypro використовує:

  • escape-послідовності – вивід на консоль символу з кодом 27 (0x18), після якого йде символ коду операції2,
  • контрольні символи із перших трьох десятків кодів ASCII.

Всі Osborne роблять те ж. Тому, процедури виводу із te_kp.c, написані на асемблері 8080 і для CP/M, нас влаштовують. Залишається вибрати правильні послідовності.

Osborne Executive надає доступ до пам’яті з кодами літер, що будуть відображатися на дисплеї – див. розділ ‘‘Memory-Mapped Video’’, стор. 435 із Osborne Executive Reference Guide. Тому, можна спробувати реалізувати більш швидкий вивід способом, який ми так любили для MS DOS (0xB800). Можливо, колись і це зроблю – user experience має покращитися. Але поки escape-послідовностей вистачить.

На сторінках 449-452 інструкції перераховано відповідні коди. Наприклад, видно, що позиціонування курсору в Osborne сумісне із Kaypro II:

osbe_esc_1
Перша частина escape-кодів Osborne Executive
CrtLocate(row, col)
int row, col;
{
    //! Фактично -- вивід на консоль ESC=p1 p2 
	CrtOut(27); CrtOut('='); CrtOut(row + 32); CrtOut(col + 32); 
}

А ось видалення всього вмісту від курсору до кінця стрічки відрізняється – для Osborne Executive це послідовність ESC T (іноді позначають як "[T") – вивести символи з десятковими кодами 27 та 84, а для Kaypro – вивести символ із десятковим кодом 24. Відрізняється також очищення екрану та ввімкнення інвертованого режиму. Всі зміни можна побачити у файлі te_osbe.c.

Після компіляції (про яку – далі) залишається ще одна операція. В комплект te входить утиліта tecf, яка дозволяє на льоту змінити деякі властивості скомпільованого редактора – ширину та висоту екрану, гарячі клавіші тощо. Якраз в традиціях CP/M. Для цього використовуються .CF файли, наприклад TE_OSBE.CF – його фрагмент нижче:

screen.rows = 24
screen.columns = 80

screen.rulerChar = .
screen.rulerTabChar = !
screen.vertChar = |
screen.horizChar = -
screen.lineNumbersChar = |

editor.maxLines = 512
editor.tabSize = 4
editor.lineNumbers = true
editor.c_language = true
editor.autoIndent = true
editor.autoList = true
editor.listBullets = "-*>"

keyname.newLine = RETURN
keyname.escape = ESC

key.up = ^K
key.down = ^J
key.left = ^H
key.right = ^L
key.begin = ^V
key.end = ^\

У свою чергу, в te_conf.c є такі змінні, як видно – порожні:

cf_cr_name:   defb 0,0,0,0,0,0,0,0  ;  8 byte  > CR key name
cf_esc_name:  defb 0,0,0,0,0,0,0,0  ;  8 byte  > ESC key name

Після компіляції, для кожного порту потрібно, утилітою tecf, вписати потрібні значення безпосередньо у виконавчий файл.

# Портування te під Osborne 1

Escape-послідовності Osborne 1 є підмножиною послідовностей Osborne Executive. Важлива відмінність – інвертованого режиму відображення (наприклад, для виділених у редакторі блоків) він не підтримує, тому, замість інвертування використав підкреслення.

Escape-коди Osborne 1, стор. 349, Osborne 1 User’s Refenece Guide.

Інша відмінність – роздільна здатність 52x24 символів. Крім того, трапився дивний баг – якщо кількість стовпців встановити 52, то при введенні останнього дозволеного символу (48-го, оскільки 4 потребує сам редактор для інтерфейсу) відбувається горизонтальний скроллінг. На 80, для Osborne Executive чи Kaypro II такого не спостерігається. Тому, як тимчасовий захід, я встановив ширину 51.

З іншого боку, 51-4 чи й 80-4 – часто замало, редактор відмовитися відкривати файли із довшими рядками, це незручно. Тому, на практиці, встановив собі, на дискеті з утилітами, 100 – поки проблем не було, хоча для більших файлів пам’яті може не вистачити.

На жаль, поки варіант для Osborne 1 випробовувався лише в емуляторі – не мав нагоди спробувати на реальному залізі.

Компілювання te

Питання, як скомпілювати – не таке тривіальне, як може здатися.

Перша проблема – автор написав свій компілятор, mescc – ‘‘Mike’s Enhanced Small C Compiler for Z80 and CP/M’’, нащадок SmallC3 – тобто, спершу слід освоїти його.

Друга проблема – цей компілятор працює лише під CP/M. Це вирішилося вдало підібраним емулятором – RunCPM4. Хоча виглядає процес цікаво:

  • cc te_osb1
    • Компілювання в .ZSM – асемблерний код Z80.
    • Розширення вибираються автоматично.
    • За замовчуванням, результат має те ж ім’я, що й вхідний файл, але інше розширення5.
  • ccopt te_osb1
    • Оптимізація.
    • Етап не обов’язковий, та й – доволі повільний, але – цікавий.
  • zsm te_osb1
    • Асемблювання в HEX-файл.
  • hextocom te_osb1
    • '’Лінкування’’ у COM-файл.
  • tecf patch te_osb1 te_osb1
    • Патчення TE_OSB1.COM згідно TE_OSB1.CF.

Завдяки можливостям RunCPM, компілятор і тексти te знаходяться поруч, на одному диску, хоча це не обов’язково, лише зручніше – цілком могли б бути на різних. На реальному залізі без HDD так би й було.

Виглядало це так:
<Пропущено багато="" виводу="">
< tecf patch te_osb1 te_osb1 нічого не виводить, то скріншот робити нецікаво. >

Оскільки процес доволі довгий навіть в емуляторі, який працює на сучасному комп’ютері, а я, у свою чергу, лінивий, створив такий скрипт bld_osb1.sub:

cc te_osb1
ccopt te_osb1
zsm te_osb1
hextocom te_osb1
tecf patch te_osb1 te_osb1

Його можна виконати (транзитивною) командою submit bld_osb1.sub.

Компіляція для Osborne Executive – аналогічна.

Особливості te

Редактор симпатичний. Звичайно, не варто його оцінювати з сучасної точки зору – ось, порівнювати його із vscode, в якому я пишу цей текст. Але, в своєму класі, хороший! Все ж, машинки, для яких він призначений, мають дуже скромні ресурси. Хоча, любителям VIM багато що здасться знайомим – він походить з цієї ж епохи.

Підтримує навігацію текстом, видалення і вставку символів6, пошук, виділення, копіювання-переміщення-видалення блоків рядків (на жаль, лише цілих рядків – не послідовності символів), підтримує макроси, і навіть – автовирівнювання.

Екран допомоги для TE_OSBE.COM, зроблений в емуляторі MAME7. Оскільки клавіші backspace чи delete відсутні, ці операції виконуються комбінаціями, Ctrl-? (Ctrl-Shift-?, іншими словами) та Ctrl-G, відповідно.

Із мінусів – відмовляється завантажувати файли, із довжиною рядка, більшою за вказану під час конфігурування, із повідомленням ‘‘Line too long’’:

Варіантів тут два – або збільшити кількість стовпців, за допомогою TECF.COM – тоді працюватиме горизонтальний скролінг:

Або, за допомогою ще однією утиліти з пакету te – TETX.COM, переформатувати файл до потрібної ширини:

TETX -W75 B:MC.PAS > B:MC75.PAS

(Стандартний командний інтерпретатор CP/M не підтримує перенаправлення безпосередньо, але > тут реалізовано самою TETX). Інші опції:

Коли зберігається відредагований файл, його вихідна версія перейменовується в .BKP – тому, для редагування, потрібно достатньо місця.

Виноски

  1. Взагалі, софт для CP/M в цьому часто був цікавим – даючи несподівано хорошу сумісність на купі різних платформ. Скажімо, підлаштування під термінал чи принтер, здійснювалося редагуванням певних байт виконавчого коду. Деяке ПЗ, типу WordStar чи Turbo Pascal мали утиліти, які це робили згідно ваших побажань. Я, коли вперше таке побачив, після пари днів занурення в CP/M спершу подумав – яка сибаритська штучка! Потім усвідомив. :-) 

  2. До прикладу, див. ANSI escape code та ADM-3A

  3. Цитуючи коментар автора, ‘‘is Small-C in the end, not ANSI, not even fully K&R.’’ 

  4. Скомпілювати на самому Osborne поки не вдалося, хоча це видається можливим. Причина – потреба вмістити на дві дискети сам компілятор, із всім йому необхідним, і джерельні тексти te, так, щоб залишилося місце на результат – .ZSM файл (із асемблерним кодом), розміром майже 124Кб. Поки вдалося звільнити лише 100Кб на одному з образів дискет. Додатково це ускладнювалося тим, що в правдивому емуляторі кожна спроба забирала декілька хвилин – до п’яти. 

  5. Типова поведінка для ПЗ CP/M. Наприклад, ASM.COM від DR – авторів CP/M, вважає, що крапка після імені файлу вказує, звідки брати ASM-файл, куди зберігати HEX-файл і лістинг. Тобто, спроба зробити: ASM TEST.ASM, спробує взяти файл A:TEST.ASM, зберегти TEST.HEX на диск S:, а TEST.LST – на диск M:. (Для позначення консолі можна використати літеру X). Більше прикладів – у пості про асемблери

  6. Це зараз такі засоби – невід’ємна частина текстового редактора. :-) 

  7. Підтримка Osborne Executive в MAME поки неповна, гірша, ніж Osborne 1, але якщо акуратно – щоб емулятор не вилітав, тестувати можна.