Искра-226/Файловая система: различия между версиями

Материал из Emuverse
(Новая страница: «{{emuverse}} '''Формат файлов BASIC 02''' — способ хранения программ на дисках Искра-226. Файловая система унаследована от Wang 2200, представление программы — оригинальное и с Wang несовместимо. Программа может храниться в двух видах: '''текстовом''' (плоский текст в...»)
 
мНет описания правки
 
(не показано 12 промежуточных версий этого же участника)
Строка 1: Строка 1:
{{emuverse}}
{{emuverse}}


'''Формат файлов BASIC 02''' — способ хранения программ на дисках [[Искра-226]]. Файловая система унаследована от [[Wang 2200]], представление программы — оригинальное и с Wang несовместимо.
'''Файловая система Искры 226''' — способ хранения файлов на дисках [[Искра-226]]. Унаследована от [[Wang 2200]] и совпадает с ней побайтово; содержимое файлов — оригинальное и с Wang несовместимо.


Программа может храниться в двух видах: '''текстовом''' (плоский текст в [[КОИ-8]]) и '''токенизированном'''. Оба вида имеют одинаковую внешнюю структуру и различаются одним байтом в заголовочном секторе.
Статья описывает файловую систему, указатель каталога и текстовое представление программ. Отдельно вынесены:


== Общее устройство ==
* [[Искра-226/Кодирование BASIC-файлов]] — токенизированная запись программы;
* [[Искра-226/Файлы данных BASIC 02]] — записи, значения и способы доступа;
* [[Искра-226/Графический буфер BASIC 02]] — формат рисунка.


Сектор — 256 байт. Файлу выделяется непрерывный диапазон секторов, границы которого записаны в каталоге. Раскладка внутри диапазона:
== Диск ==
 
Физический сектор — 128 байт; 77 дорожек по 26 секторов, одна сторона. Физические сектора попарно объединены в логические по 256 байт со сквозной нумерацией. Далее везде подразумеваются логические сектора. Полный объём тома — 1001 сектор, 256 256 байт.
 
Типы файлов:
 
* '''ПФ''' — программный файл: программа на Бейсике в текстовом либо оттранслированном виде;
* '''ФД''' — файл данных.
 
Файлу выделяется непрерывный диапазон секторов, границы записаны в указателе каталога.


{| class="wikitable"
{| class="wikitable"
Строка 16: Строка 27:
| следующие N || поток содержимого
| следующие N || поток содержимого
|-
|-
| … || резерв, заполнен нулями
| … || резерв, нули
|-
|-
| последний выделенный || control record
| последний выделенный || концевая запись
|}
|}


Как и в Wang, при перезаписи файла более коротким содержимым '''старые данные в резерве не затираются'''. В резерве могут лежать читаемые фрагменты предыдущих версий программы, иногда в другом представлении. Их нельзя принимать за часть текущего файла.
Размер файла на диске не меняется, поэтому при перезаписи более коротким содержимым '''хвост не затирается''': там остаются фрагменты предыдущих версий, иногда в другом представлении. Обработку следует прекращать на первой встреченной концевой записи.
 
Диски прямого доступа (запись по абсолютным адресам секторов) указателя каталога не имеют; формат содержимого таких дисков задаёт программа пользователя. Загрузочные диски с интерпретатором имеют собственный формат: нулевой сектор начинается сигнатурой <code>06 90 09 90 07 90</code>, за ней 18 знаков имени и даты версии.
 
== Указатель каталога ==
 
Начинается с сектора 0. Первые 16 байт нулевого сектора — параметры диска:
 
{| class="wikitable"
! Смещение !! Размер !! Значение
|-
| 0–1 || 2 || размер указателя каталога в секторах (<code>LS</code>), старший байт первым
|-
| 2–3 || 2 || текущий конец каталога — первый свободный сектор
|-
| 4–5 || 2 || конец области каталога
|-
| 6–15 || 10 || нули
|}
 
Размер указателя задаётся при создании каталога оператором <code>SCRATCH DISK</code> параметром <code>LS=</code>, по умолчанию 24, допустимо 1…255; в дальнейшем не меняется. В нулевом секторе помещается 15 записей, в остальных 16. Неиспользованные записи заполнены нулями.
 
Записи '''не сгруппированы''' в начале указателя и не упорядочены по секторам файлов: номер сектора, в который попадает запись, вычисляется хешированием имени. Для чтения каталога надо пройти все его секторы, пропуская нулевые записи.
 
=== Хеш имени файла ===
 
Номер сектора указателя вычисляется по «старому» хешу Wang 2200:
 
имя дополнить пробелами до восьми байт
tmp = 0
для каждого байта имени:  tmp = tmp XOR байт
tmp = 3 × tmp
tmp = (tmp mod 256) + (tmp div 256)
сектор = tmp mod LS
 
Свёртка выполняется исключающим ИЛИ, не сложением. «Новый» хеш Wang, введённый в MVP OS 2.5, на Искре не применяется.
 
Хеш '''вырождается при <code>LS</code>, кратном трём''': после умножения на 3 и складывания половинок результат всегда кратен трём, поэтому занятыми оказываются только каждый третий сектор указателя. При <code>LS = 24</code> все записи попадают в секторы 0, 12, 15 и 18.
 
Запись кладётся в первый свободный слот своего сектора, слоты заполняются подряд от начала. Правило переполнения сектора неизвестно.
 
Освобождение слота выполняется '''обнулением первых восьми байт''' записи; имя при этом остаётся на диске. Оператор <code>SCRATCH</code> запись не обнуляет, а помечает.


== Запись каталога ==
== Запись каталога ==


16 байт, побайтово совпадает с Wang 2200.
16 байт, совпадает с Wang 2200.


{| class="wikitable"
{| class="wikitable"
! Смещение !! Размер !! Значение
! Смещение !! Размер !! Значение
|-
|-
| 0 || 1 || статус: <code>10</code> — активна, <code>11</code> — удалена (scratched), <code>00</code> — свободна
| 0 || 1 || статус, битовое поле; '''бит 0''' — файл вычеркнут
|-
|-
| 1 || 1 || тип файла: <code>80</code> — программа, <code>00</code> — данные
| 1 || 1 || тип файла: <code>80</code> — программа, <code>00</code> — данные
Строка 43: Строка 95:
|}
|}


Байт типа '''не различает''' текстовое и токенизированное представление: у обоих <code>80</code>.
Наблюдаемые значения статуса: <code>10</code> — активна, <code>11</code> и <code>21</code> — вычеркнута, <code>00</code> — свободна. Сравнивать статус на точное равенство нельзя, значим только бит 0. Бит 5 (значение <code>21</code>) предположительно помечает переименование.
 
Байт типа '''не различает''' текстовое и оттранслированное представление программы: у обоих <code>80</code>.


Указатель каталога всегда начинается с нулевого сектора диска; за ним идёт область каталога. Число секторов указателя задаётся при создании каталога оператором <code>SCRATCH DISK</code> параметром <code>LS=</code>, по умолчанию равно 24 и в дальнейшем не меняется; допустимы значения от 1 до 255. В нулевом секторе помещается до 15 записей, в остальных — до 16: первые 16 байт нулевого сектора занимает блок параметров диска. Номер сектора указателя, в который попадает имя файла, вычисляется функцией от самого имени, поэтому порядок имён в указателе не совпадает с порядком размещения файлов в области каталога.<ref name="balasanyan" />
Оператор <code>LIST DC</code> выводит типы как <code>P</code> (программный), <code>D</code> (данные), <code>SP</code> и <code>SD</code> (вычеркнутые), что соответствует сочетанию байта статуса и байта типа.<ref name="balasanyan" />


Оператор <code>LIST DC</code> выводит типы файлов как <code>P</code> (программный), <code>D</code> (файл данных), <code>SP</code> и <code>SD</code> (вычеркнутые из каталога программный и файл данных соответственно), что соответствует сочетанию байта статуса и байта типа в записи.<ref name="balasanyan" />
Тип «данные» ничего не говорит о внутреннем устройстве файла: он может содержать как логические записи, так и сырые блоки, записанные оператором <code>DATA SAVE BA</code>.


=== Пример ===
=== Пример ===
  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
10 80 00 31 00 3F 00 00 44 49 47 20 44 45 4D 20
└───┘ └───┘ └───┘      └─────────────────────┘
Активная запись, программа, секторы 49…63, имя <code>DIG DEM</code>.


10 80 00 31 00 3F 00 00 44 49 47 20 44 45 4D 20
== Размещение файлов ==


Активная запись, программа, секторы 49…63, имя <code>DIG DEM</code>.
* Файлы лежат подряд в порядке создания, диапазоны секторов не пересекаются.
* Место вычеркнутого файла заново не занимается: <code>SCRATCH</code> только помечает запись.
* Первый файл начинается с сектора <code>LS</code>, сразу за указателем.
* Поле «текущий конец» равно последнему занятому сектору плюс единица, но обрезается по концу области каталога; при разборе границу надёжнее брать по записям каталога.


== Заголовочный сектор ==
== Заголовочный сектор ==
Строка 64: Строка 125:
| 1–8 || имя файла, дополнено пробелами
| 1–8 || имя файла, дополнено пробелами
|-
|-
| 9 || признак формата записи, см. ниже
| 9 || признак формата записи
|-
|-
| 10–255 || нули
| 10–255 || нули
|}
|}


Байт 9 — единственный признак, по которому различаются два представления программы. Наблюдались значения <code>20</code> (текстовое) и <code>21</code> (токенизированное), каждое на двух файлах.
Байт 9 (в справочнике<ref name="vtoraya" /> назван «признак защиты») — битовое поле, единственный признак, различающий два представления программы: '''бит 0''' — программа оттранслирована (параметр <code>T</code> оператора <code>SAVE DC</code>), '''бит 2''' — защищена (параметр <code>P</code>); оба вместе соответствуют параметру <code>G</code>.
 
=== Связь с параметрами оператора SAVE DC ===
 
Документация<ref name="balasanyan" /> описывает три параметра специальных форматов записи программы:
 
{| class="wikitable"
! Параметр !! Действие
|-
| <code>T</code> || программа записывается в оттранслированной форме — во внутреннем формате машины, что сокращает занимаемое место и время загрузки
|-
| <code>P</code> || программа защищается от просмотра и записи; после загрузки возможно только выполнение, режим сохраняется до оператора <code>CLEAR</code>
|-
| <code>G</code> || оттранслированная и защищённая форма одновременно
|}
 
Отсюда следует, что '''текстовое представление — это режим по умолчанию''', а токенизированное включается явным указанием параметра <code>T</code>. Термин «оттранслированная форма» в документации обозначает именно токенизированную запись.
 
Документированные значения байта 9 (в источнике он назван «признак защиты»):<ref name="vtoraya" />


{| class="wikitable"
{| class="wikitable"
Строка 101: Строка 144:
|}
|}


Таким образом байт 9 — битовое поле: '''бит 0''' — программа оттранслирована (параметр <code>T</code>), '''бит 2''' — программа защищена (параметр <code>P</code>); сочетание обоих соответствует параметру <code>G</code>. Значения <code>22</code> и <code>23</code> не используются.
Значения <code>22</code> и <code>23</code> не используются. Текстовое представление — режим по умолчанию, оттранслированное включается явным параметром <code>T</code>.


Значения <code>20</code> и <code>21</code> наблюдались на дисковых образах, <code>24</code> и <code>25</code> взяты из документации.
Защищённая программа после загрузки может только выполняться; режим снимается оператором <code>CLEAR</code>.


== Секторы потока ==
== Секторы потока ==


Первые два байта каждого сектора потока — служебные, в содержимое не входят.
Первые два байта каждого сектора программного потока — служебные, в содержимое не входят. У секторов файла данных служебный заголовок занимает '''один''' байт.


'''Байт 0''' — позиция сектора:
'''Байт 0''' — позиция сектора:


{| class="wikitable"
{| class="wikitable"
! Значение !! Смысл
! Код !! Смысл
|-
|-
| <code>02</code> || первый сектор потока
| <code>02</code> || первый сектор потока
|-
|-
| <code>8F</code> || промежуточный
| <code>03</code> || последний сектор потока
|-
|-
| <code>03</code> || последний
| <code>1C</code> || концевая запись
|-
| <code>8B</code> || запись целиком в одном секторе (только файлы данных)
|-
| <code>8F</code> || промежуточный сектор
|}
|}


В токенизированных программах все секторы потока наблюдались с маркером <code>02</code>; позиционная разметка <code>02</code>/<code>8F</code>/<code>03</code> подтверждена на текстовых файлах и на потоке значений переменных. Причина различия не установлена.
В оттранслированных программах все секторы потока идут с маркером <code>02</code>. Позиционная разметка <code>02</code>/<code>8F</code>/<code>03</code> наблюдается в текстовых файлах и в потоках данных.


'''Байт 1''' — только у программных секторов. Во всех исследованных потоках программы он равен <code>80</code>.
'''Байт 1''' программных секторов равен <code>80</code>. Как признак «программа или данные» он непригоден: у секторов данных на позиции 1 стоит первый байт идентификатора значения. Надёжные признаки — байт 9 заголовочного сектора и байт типа записи каталога.


{{Внимание|У секторов данных служебный заголовок занимает '''один''' байт, а не два. То, что во всех наблюдавшихся секторах данных на позиции 1 стоял <code>00</code>, объясняется не разметкой потока, а тем, что это первый байт двухбайтового идентификатора значения, и <code>00</code> в нём означает числовой тип. Для сектора, начинающегося со строкового значения, значение будет другим. Использовать байт 1 как признак «программа или данные» нельзя; надёжный признак — байт 9 заголовочного сектора и байт типа в записи каталога.}}
== Концевая запись ==
 
Двухбайтовая длина служебного заголовка программных секторов подтверждается арифметикой: длины записей строк сходятся только при пропуске двух байтов на каждой пересекаемой границе сектора.
 
В токенизированном файле сначала идут секторы программы, за ними могут следовать секторы значений переменных с собственной нумерацией.
 
Маркер <code>03</code> имеет содержательный смысл: документация<ref name="balasanyan" /> описывает файл как область, в которой между последней записью данных и последним сектором файла остаются неиспользованные секторы, а концевая запись помечает сектор, откуда можно продолжать запись. Таким образом <code>03</code> — не просто «последний по счёту сектор», а граница записанной области, и всё, что лежит за ней до конца выделенного диапазона, к текущему содержимому файла не относится.
 
== Control record ==
 
Лежит в '''последнем выделенном''' секторе, а не сразу за содержимым.


  1C <длина: 2 байта, старший первым>
  1C <длина: 2 байта, старший первым>


Остаток сектора — нули. Маркер <code>1C</code> соответствует по роли байту <code>20</code> в Wang. Второй источник<ref name="vtoraya" /> описывает эту структуру как признак конца файла <code>1C</code>, за которым во втором и третьем байтах сектора записано число реально занятых секторов, а остальные байты нулевые; последний сектор файла данных устроен так же, как последний сектор программного файла.
Остаток сектора — нули. Соответствует по роли байту <code>20</code> в Wang.


Документация<ref name="balasanyan" /> отдельно указывает, что последний сектор файла отводится под служебную информацию, а концевая запись занимает ещё один сектор, поэтому при создании файла его размер следует заказывать на два сектора больше, чем требуется собственно под данные.
Счётчик равен '''собственной позиции записи от начала файла''', считая с единицы, то есть числу занятых секторов вместе с заголовком. Он же — графа «Использовано» в выдаче <code>LIST DC</code>.


Счётчик соответствует графе «Использовано», которую показывает оператор <code>LIST DC</code>. Согласно документации<ref name="balasanyan" /> он '''не поддерживается системой автоматически''': значение заносит прикладная программа оператором <code>DATA SAVE DC END</code>, записывающим односекторную концевую запись в текущий сектор из таблицы устройств. Если признак конца данных не записан, в графе «Использовано» всегда стоит 00001; если записан — число реально использованных секторов.
* У программных файлов концевую запись пишет сам оператор <code>SAVE DC</code>; она есть всегда.
* У файлов данных её пишет прикладная программа оператором <code>DATA SAVE DC END</code>. Если признак конца не записан, в графе «Использовано» стоит 00001.
* Оператор <code>DATA SAVE DC OPEN</code> пишет в '''последний''' сектор файла запись <code>1C 00 01</code> — единственный случай, когда счётчик не равен позиции.


Там, где значение выставлено, оно равно '''заголовок + секторы содержимого + сам control record''', то есть совпадает с правилом Wang:
Запись лежит не обязательно в последнем выделенном секторе: если файлу дали запас или его положили на место вычеркнутого файла большего размера, за ней остаётся нулевой хвост.


{| class="wikitable"
Счётчик — не инвариант файловой системы и при разборе ненадёжен: у файлов, записанных не операторами <code>DATA SAVE DC</code>, он произволен. Границы файла следует брать из каталога.
! Файл !! Секторов содержимого !! Счётчик !! Ожидаемо
|-
| <code>ФС</code> || 5 || 7 || 1+5+1 = 7
|-
| <code>ДЕМ6</code> || 16 || 18 || 1+16+1 = 18
|}
 
{{Внимание|Счётчик не является инвариантом файловой системы и при разборе ненадёжен. У <code>#СТАТИСТ</code> он равен 48 при 46 секторах содержимого — значение, по-видимому, осталось от предыдущей, более длинной версии программы, остатки которой лежат в резерве того же файла. У <code>DIG DEM</code> счётчик равен 6 при 5 секторах содержимого, то есть на единицу меньше ожидаемого; возможная причина в том, что там последней операцией была запись потока данных, а не программы. Границы файла следует брать из каталога, а конец данных определять по структуре записей.}}


== Текстовое представление ==
== Текстовое представление ==


Программа хранится плоским текстом. Кодировка — КОИ-8 (ГОСТ 19768-74): прописная кириллица в 0xE0–0xFF, строчная в 0xC0–0xDF. Номера строк записаны обычными ASCII-цифрами.
Программа хранится плоским текстом. Кодировка — [[КОИ-8]] (ГОСТ 19768-74): прописная кириллица в <code>E0</code>–<code>FF</code>, строчная в <code>C0</code>–<code>DF</code>. Номера строк записаны обычными цифрами.


* Разделитель строк — байт '''<code>85</code>'''.
* Разделитель строк — байт '''<code>85</code>'''.
Строка 165: Строка 196:
* Байт <code>24</code> (<code>$</code>) отображается на экране Искры как <code>¤</code>.
* Байт <code>24</code> (<code>$</code>) отображается на экране Искры как <code>¤</code>.


Выбор <code>85</code> возможен именно потому, что кириллица занимает только верхнюю четверть кодовой таблицы и диапазон 0x80–0x9F остаётся свободным. К самой кодировке КОИ-8 это соглашение отношения не имеет и за пределами Искры не встречается.
Байт <code>85</code> свободен потому, что диапазон <code>80</code>–<code>9F</code> в КОИ-8 не занят. Тем же байтом машина разделяет строки в символьном буфере операторов <code>SAVE</code> и <code>LOAD</code> и выдаёт нажатие клавиши CR/LF.


Разбор: склеить содержимое секторов, отбрасывая по два служебных байта, разбить по <code>85</code>, отбросить нули.
Разбор: склеить содержимое секторов, отбрасывая по два служебных байта, разбить по <code>85</code>, отбросить нули.
Строка 175: Строка 206:
Заголовок сектора, затем <code>5 REM ПЕТРЕНКО …</code>, разделитель, <code>8 PRINT …</code>.
Заголовок сектора, затем <code>5 REM ПЕТРЕНКО …</code>, разделитель, <code>8 PRINT …</code>.


== Токенизированное представление ==
== Виды дисков ==
 
=== Сборка потока ===
 
Склеить содержимое секторов с байтом 1 равным <code>80</code>, отбрасывая по два служебных байта у каждого. Далее смещения даны от начала полученного потока.
 
=== Пролог и таблицы ===
 
Поток начинается с трёх 16-битных длин, '''старший байт первым''', за которыми следуют три таблицы:


{| class="wikitable"
{| class="wikitable"
! Смещение !! Размер !! Значение
! Вид !! Признак
|-
| 0 || 2 || L1 — длина таблицы 1 в байтах, запись 8 байт
|-
|-
| 2 || 2 || L2 — длина таблицы 2 в байтах, запись 4 байта
| с каталогом || байты 0–1 нулевого сектора — разумный <code>LS</code>, дальше 16-байтовые записи
|-
|-
| 4 || 2 || L3 — длина таблицы 3 в байтах, запись 4 байта
| загрузочный || сектор 0 начинается с <code>06 90 09 90 07 90</code>
|-
| 6 || L1 || таблица 1
|-
| 6+L1 || L2 || таблица 2
|-
| 6+L1+L2 || L3 || таблица 3
|}
 
'''Программа начинается по смещению <code>6 + L1 + L2 + L3</code>.'''
 
Проверено на трёх файлах:
 
{| class="wikitable"
! Файл !! L1 !! L2 !! L3 !! Старт !! Первая строка
|-
|-
| <code>DIG DEM</code> || 24 || 20 || 0 || 50 || <code>0 GOTO 10</code>
| пакет ассемблера || сектор 0 начинается с <code>7E E1 F3 ED E2</code> (<code>~АСМБ</code>)
|-
|-
| <code>#СТАТИСТ</code> || 216 || 488 || 108 || 818 || <code>999 REM  КОНЕЦ</code>
| прямого доступа || каталога нет, есть заголовочные секторы <code>01 &lt;имя&gt; &lt;признак&gt;</code>
|-
|-
| <code>ДЕМ6</code> || 392 || 256 || 0 || 654 || <code>10 REM "ДЕМ6". ГОРОСКОП</code>
| пустой || нули
|}
|}
Формула даёт точную границу, эвристический поиск начала программы не требуется.
==== Таблица 1 ====
Записи по 8 байт. Байты 0–1 — адрес, младший первым, строго возрастающий от записи к записи. Шаг между соседними адресами принимает значения 2, 4, 8, 12, 48, что соответствует размерам объектов: 2 байта — целочисленная переменная BASIC 02, 8 байт — число в BCD, кратные — массивы. Назначение байтов 2–7 не установлено.
'''Таблица 1 описывает переменные, объявленные в <code>DIM</code>,''' и номер записи в ней равен индексу переменной в коде. В файле <code>ДЕМ6</code> три оператора <code>DIM</code> перечисляют индексы <code>00</code>–<code>05</code>, <code>06</code>–<code>29</code> и <code>2A</code>–<code>30</code>, то есть 49 переменных подряд; L1 = 392 = 49 × 8. Совпадение точное.
==== Таблицы 2 и 3 ====
Записи по 4 байта: <code>&lt;адрес: 2 байта, младший первым&gt; &lt;флаг&gt; &lt;байт&gt;</code>. Флаг принимает значения <code>10</code>, <code>21</code>, <code>80</code>, <code>81</code>, <code>90</code>, <code>91</code>, <code>A0</code>, <code>A1</code>. Встречаются записи с нулевым адресом — предположительно незанятые слоты. Формат записей в обеих таблицах одинаков, граница между ними определяется только счётчиками пролога.
'''Нумерация индексов сквозная''': таблица 1 занимает индексы от 0 до (L1/8 − 1), таблица 2 продолжает нумерацию. В <code>ДЕМ6</code> индексы <code>31</code>–<code>3F</code> адресуют первые пятнадцать записей таблицы 2, и именно у этих пятнадцати адреса образуют непрерывный ряд с шагом 8 (8-байтовые числа BCD).
Оставшиеся записи таблицы 2 в коде не адресуются, а их количество равно числу записей таблицы 1 — 49 в <code>ДЕМ6</code> и 3 в <code>DIG DEM</code>. Похоже, каждой размерной переменной соответствует второй дескриптор в низкой области памяти, однако на третьем файле это разбиение не проверяется, поэтому пока наблюдение, а не правило.
{{Внимание|1=Соответствие «индекс переменной в коде → имя переменной» не установлено. В таблицах имена в явном виде отсутствуют. Индексы, судя по наблюдениям, назначаются по порядку объявления и первого появления переменной: в <code>#СТАТИСТ</code> <code>F¤</code>=00, <code>N3</code>=0E, <code>N6</code>=11, <code>F1¤</code>=12, <code>E</code>=1B, <code>E7%</code>=1C, <code>U1¤()</code>=30, <code>F%</code>=5C, <code>N7</code>=5D, <code>W0</code>=7D, <code>U9%</code>=81. Это главное препятствие для получения читаемого листинга.
Известно, что имена ограничены буквой с необязательной цифрой — оператор <code>LIST V</code> выводит переменные в алфавитном порядке от <code>A</code> до <code>Z9</code>, группируя их по типам: целые, действительные, символьные, затем массивы целых, действительных и символьных.<ref name="balasanyan" /> Такое имя укладывается в девять бит, что делает вероятным его размещение в паре «флаг + байт» записей таблиц 2 и 3. Порядок записей в таблицах при этом не алфавитный, а соответствует порядку объявления переменных.}}
=== Записи строк ===
Программа — последовательность записей, разделённых байтом '''<code>FE</code>'''. Перед первой записью разделителя нет.
&lt;номер строки: 2 байта BCD&gt; &lt;len: 1 байт&gt; &lt;тело&gt;
<code>len</code> считается '''включая сам байт len''' и до следующего <code>FE</code>. Следующий разделитель находится по адресу <code>адрес(len) + len</code>.
В отличие от текстового представления, записи '''пересекают''' границу сектора; два служебных байта нового сектора в длину не входят.
=== Операторы ===
Тело записи — последовательность операторов:
&lt;токен глагола: 1 байт&gt; &lt;len: 1 байт&gt; &lt;операнды: len байт&gt;
Здесь <code>len</code> — длина только операндов, сам байт len не считается. <code>len = 00</code> означает оператор без операндов, например голый <code>PRINT</code>.
Наличие явной длины у каждого оператора позволяет разрезать программу на операторы, ещё не зная значений токенов. Эта особенность вынужденная: в отличие от Wang, где многословные команды собираются из нескольких токенов вперемешку с обычным ASCII и границы видны по самому потоку, у Искры весь текст программы переведён в токены и поток непрозрачен.
==== Пример разбора ====
Строка 2000 файла <code>#СТАТИСТ</code>, длина 0x54 = 84:
20 00 54
23 01 23                          GOSUB ' 35
4C 39 E3 1F «БУДЕТЕ …» DD 00 DD E3 12 «-[1] ИЛИ ДВУМЯ [2]» DD
                                  PRINT "…";F¤;"…";
41 01 5C                          INPUT F%
36 03 5D D9 0E                    N7=N3
24 06 0E D7 11 D3 20 01          IF N3&lt;N6THEN2001
36 03 5D D9 11                    N7=N6
Сумма: 3 + 59 + 3 + 5 + 8 + 5 = 83, плюс байт длины = 84.
== Таблица токенов ==
=== Глаголы ===
Основной массив значений восстановлен из прошивки интерпретатора (алфавитный список ключевых слов по смещению 0x1840 и 51-байтовый массив перестановки по 0x19B6). Отмеченные записи проверены или исправлены сопоставлением токенизированной и текстовой версий одной программы.
{| class="wikitable"
! Токен !! Оператор !! Примечание
|-
| <code>21</code> || GOTO || подтверждено
|-
| <code>22</code> || GOSUB || подтверждено
|-
| <code>23</code> || GOSUB' || в прошивочной таблице пропуск; значение выведено из данных
|-
| <code>24</code> || IF || подтверждено
|-
| <code>25</code> || KEYIN ||
|-
| <code>26</code> || ON ||
|-
| <code>27</code> || DEFFN' ||
|-
| <code>28</code> || PRINTUSING || в опубликованной таблице ошибочно указан GOSUB'; исправлено по данным
|-
| <code>29</code> || DATA || подтверждено
|-
| <code>2A</code> || SAVE ||
|-
| <code>2B</code> || RENUMBER ||
|-
| <code>2C</code> || CLEAR ||
|-
| <code>2D</code> || LOAD ||
|-
| <code>2E</code> || LIST ||
|-
| <code>2F</code> || RUN ||
|-
| <code>35</code> || LET ||
|-
| <code>36</code> || ''(присваивание без ключевого слова)'' || подтверждено
|-
| <code>40</code> || $GIO ||
|-
| <code>41</code> || INPUT || подтверждено
|-
| <code>42</code> || STOP ||
|-
| <code>43</code> || AND( ||
|-
| <code>44</code> || READ || подтверждено
|-
| <code>45</code> || BOOL ||
|-
| <code>46</code> || DIM || подтверждено
|-
| <code>47</code> || CONVERT ||
|-
| <code>48</code> || PACK( ||
|-
| <code>4A</code> || ADD ||
|-
| <code>4B</code> || BIN( ||
|-
| <code>4C</code> || PRINT || подтверждено
|-
| <code>4D</code> || ROTATE ||
|-
| <code>4E</code> || COM ||
|-
| <code>50</code> || HEXPRINT ||
|-
| <code>52</code> || NEXT || подтверждено
|-
| <code>53</code> || REWIND ||
|-
| <code>54</code> || SELECT || подтверждено
|-
| <code>55</code> || BACKSPACE ||
|-
| <code>56</code> || REM || подтверждено
|-
| <code>57</code> || FOR || подтверждено
|-
| <code>58</code> || SKIP ||
|-
| <code>59</code> || END ||
|-
| <code>5A</code> || DEFFN ||
|-
| <code>5C</code> || RES ||
|-
| <code>5D</code> || UNPACK( || подтверждено
|-
| <code>5E</code> || RETURN ||
|-
| <code>5F</code> || TRACE ||
|-
| <code>61</code> || OR( ||
|-
| <code>62</code> || XOR( ||
|-
| <code>64</code> || INIT ||
|-
| <code>6D</code> || COPY ||
|-
| <code>74</code> || DATA LOAD DC || выведено из данных
|-
| <code>75</code> || DATA LOAD DC OPEN T || выведено из данных
|-
| <code>79</code> || DBACKSPACE ||
|-
| <code>7A</code> || DSKIP ||
|-
| <code>7B</code> || LIMITS ||
|-
| <code>7E</code> || MOVE ||
|-
| <code>81</code> || SCRATCH ||
|-
| <code>83</code> || VERIFY ||
|}
Значения назначены не по алфавиту, а тематическими группами с запасом внутри каждой: управление ходом выполнения в 0x21–0x2F, ввод-вывод около 0x41–0x4C, дисковые операции в 0x74–0x83. Составные дисковые команды получают '''один''' токен на всю фразу, тогда как в Wang та же команда собирается из нескольких (<code>DATA</code> + <code>LOAD</code> + <code>DC</code>).
Документация<ref name="balasanyan" /> описывает также операторы <code>DATA SAVE DC END</code>, <code>DATA SAVE DC CLOSE</code> и <code>DATA LOAD DC OPEN</code>. Последний соответствует найденному токену <code>75</code>, поэтому остальные с высокой вероятностью занимают свободные значения в диапазоне 0x70–0x78 — при разборе новых файлов имеет смысл проверять этот участок в первую очередь.
=== Операнды ===
{| class="wikitable"
! Токен !! Значение !! Достоверность
|-
| <code>00</code>–<code>~BF</code> || ссылка на переменную по индексу || подтверждено
|-
| <code>D0</code> || <code>)</code> || вероятно
|-
| <code>D1</code> || TO || подтверждено
|-
| <code>D3</code> || THEN, далее 2 байта BCD — номер строки || подтверждено
|-
| <code>D4</code> || <code>&gt;</code> || вероятно
|-
| <code>D7</code> || <code>&lt;</code> || подтверждено
|-
| <code>D9</code> || <code>=</code> || подтверждено
|-
| <code>DB</code> || <code>#</code> || подтверждено
|-
| <code>DC</code> || <code>/</code> || вероятно
|-
| <code>DD</code> || <code>;</code> || подтверждено
|-
| <code>DE</code> || <code>,</code> || подтверждено
|-
| <code>E0</code> || ссылка на массив, далее индекс переменной || подтверждено
|-
| <code>DF</code> || <code>TAB(</code> || подтверждено
|-
| <code>E2</code> || шестнадцатеричный литерал <code>HEX(…)</code>: <code>E2 &lt;len&gt; &lt;len байт&gt;</code> || подтверждено
|-
| <code>E3</code> || строковый литерал: <code>E3 &lt;len&gt; &lt;len байт КОИ-8&gt;</code> || подтверждено
|-
| <code>E7</code> || числовая константа: <code>E7 &lt;2 байта BCD&gt;</code>, диапазон 0–9999 || подтверждено
|-
| <code>E8</code> || числовая константа: <code>E8 &lt;байт BCD&gt;</code>, диапазон 0–99 || подтверждено
|-
| <code>E9</code> || <code>*</code> || вероятно
|-
| <code>EA</code> || <code>+</code> || вероятно
|-
| <code>EB</code> || <code>(</code> || вероятно
|-
| <code>FE</code> || разделитель записей строк || подтверждено
|}
Числовые константы кодируются двумя токенами в зависимости от величины: <code>E8</code> — один байт BCD (0–99), <code>E7</code> — два байта BCD (0–9999). Представление дробных констант в исследованных файлах не встретилось. Номер метки в <code>GOSUB'</code> хранится '''двоичным''', а не в BCD.
=== Индексация массивов ===
У обращения к элементу массива '''нет открывающей скобки''': ссылка на переменную сама открывает список индексов, а <code>D0</code> его закрывает.
01 32 D0        →  01(32)
2A 03 E8 01 D0 D0  →  2A(03,1)
Токен <code>EB</code> используется только как группирующая скобка в выражениях:
EB 34 E9 33 E9 E8 01 D0  →  (34*33*1)
Разборщик, ожидающий <code>EB</code> перед индексом массива, рассинхронизируется.
== Поток значений переменных ==
Секторы, следующие за программой в токенизированном файле, содержат значения переменных, записанные в том же формате, что и обычные файлы данных. Структура описана в документации<ref name="balasanyan" />.
Служебная информация в секторе двух видов:
* '''идентификатор сектора''' — 1 байт в начале сектора, значение <code>02</code> (признак данных);<ref name="vtoraya" /> под данные остаются 255 байт;
* '''идентификатор значения''' — 2 байта перед каждым значением, содержат тип (числовое или символьное) и длину.
Размеры значений:
{| class="wikitable"
! Тип !! Значение !! Со служебными байтами !! Значений в секторе
|-
| целое || 2 байта || 4 байта || 63
|-
| действительное || 8 байт || 10 байт || 25
|-
| символьное || длина значения || длина + 2 || —
|}
Значение, не помещающееся в секторе целиком, переносится в следующий сектор полностью. Элементы массивов записываются построчно.
=== Пример ===
В файле <code>DIG DEM</code> сектор данных начинается с идентификатора сектора <code>02</code>, за которым идут 25 записей по 10 байт:
00 08 &lt;8 байт значения&gt;
Идентификатор <code>00 08</code> означает числовое значение длиной 8 байт. Двадцать пятая запись заканчивается на пятом байте от конца сектора, оставшиеся 5 байт не используются: 1 + 25 × 10 + 5 = 256. Расчёт сходится точно и подтверждает однобайтовую длину идентификатора сектора.
== Алгоритм разбора ==
# Прочитать запись каталога: первый и последний сектор, тип должен быть <code>80</code>.
# Прочитать первый сектор: проверить байт 0 = <code>01</code>, взять имя, прочитать байт 9.
# Если байт 9 = <code>20</code>: склеить содержимое секторов, разбить по <code>85</code>, отбросить нули, перекодировать КОИ-8. Готово.
# Если байт 9 = <code>21</code>: собрать поток из секторов с байтом 1 = <code>80</code>; прочитать L1, L2, L3; перейти к смещению <code>6 + L1 + L2 + L3</code>.
# Для каждой записи: номер строки из двух байтов BCD, длина из третьего, тело до следующего <code>FE</code>. Если по отсчитанной длине не оказалось <code>FE</code> — поток рассинхронизирован, разбор остановить.
# Тело разрезать на операторы по схеме <code>&lt;глагол&gt;&lt;len&gt;&lt;операнды&gt;</code>.
Байт длины в каждой записи и в каждом операторе даёт бесплатную проверку целостности на каждом шаге.


== Отличия от Wang 2200 ==
== Отличия от Wang 2200 ==
Строка 510: Строка 229:
| Запись каталога || 16 байт || совпадает побайтово
| Запись каталога || 16 байт || совпадает побайтово
|-
|-
| Маркер control record || <code>20</code> || <code>1C</code>
| Хеш имени || «старый» и «новый» || только «старый»
|-
| Маркер концевой записи || <code>20</code> || <code>1C</code>
|-
|-
| Маркер заголовка || <code>40</code> (<code>50</code> для защищённых) || <code>01</code>
| Маркер заголовка || <code>40</code> (<code>50</code> для защищённых) || <code>01</code>
Строка 516: Строка 237:
| Маркеры секторов || битовое поле в старшей тетраде || отдельные значения <code>02</code>/<code>8F</code>/<code>03</code>
| Маркеры секторов || битовое поле в старшей тетраде || отдельные значения <code>02</code>/<code>8F</code>/<code>03</code>
|-
|-
| Конец строки в программе || <code>0D 00 00</code> || <code>FE</code> как разделитель
| Представление программы || ключевые слова в токенах, остальное ASCII || несовместимо, см. [[Оттранслированное представление BASIC 02]]
|-
| Конец блока || <code>FD</code> (EOB) / <code>FE</code> (EOD) || не используется
|-
| Диапазон токенов || 0x80–0xFB, 124 значения || глаголы 0x21–0x83, операнды 0xD0–0xEB
|-
| Текст в программе || ключевые слова в токенах, остальное обычный ASCII || всё в токенах, ASCII только внутри строковых литералов
|-
| Переменные || имена в открытом виде || индексы в таблицу
|-
| Длина оператора || отсутствует || обязательный байт после каждого глагола
|}
|}


Таблицы токенов не имеют между собой ничего общего: систематического сдвига нет, совпадений по отдельным байтам нет. Инструментарий Wang для детокенизации переиспользовать нельзя. Совпадает только уровень файловой системы.
Совпадает только уровень файловой системы. Инструментарий Wang для разбора самих программ непригоден.
 
Вероятная причина расхождения — кодировка. В Wang верхняя половина таблицы свободна и отдана под ключевые слова; у Искры она занята кириллицей, поэтому глаголы перенесены вниз, а от литерального ASCII в потоке отказались полностью.
 
== Не установлено ==
 
# '''Имена переменных.''' Главное препятствие для читаемого листинга. Возможный путь — сопоставление токенизированной и текстовой версий одной программы, если обе сохранились на диске.
# Полная таблица токенов: часть значений в диапазонах 0x30–0x34, 0x37–0x3F, 0x65–0x78 не занята в известной таблице.
# Представление дробных числовых констант.
# Байты 2–7 записи таблицы 1 и байты 2–3 записей таблиц 2 и 3.
# Природа двухбайтового хвоста без префикса в конце каждого оператора <code>DATA</code> (<code>C9 04</code>, <code>EE 04</code>, <code>00 00</code> в <code>ДЕМ6</code>): в длину оператора он входит, но ни под <code>E7</code>, ни под <code>E8</code> не подходит.
# Причина различия разметки секторов между токенизированными и текстовыми потоками: в текстовых файлах наблюдается позиционная схема <code>02</code>/<code>8F</code>/<code>03</code>, в токенизированных все секторы программы идут с маркером <code>02</code>.
# Токены операторов <code>DATA SAVE DC END</code> и <code>DATA SAVE DC CLOSE</code>.


== Примечания ==
== Примечания ==


<references>
<references>
<ref name="balasanyan">Баласанян В. Э., Богдюкевич С. В., Шахвердов В. А. Программирование на микроЭВМ «Искра 226». — М.: Финансы и статистика, 1987. — 264 с.: ил. — разделы 5.1, 5.2, 11.5, 18.1, 18.4, 18.7.</ref>
<ref name="balasanyan">Баласанян В. Э., Богдюкевич С. В., Шахвердов В. А. Программирование на микроЭВМ «Искра 226». — М.: Финансы и статистика, 1987. — 264 с.: ил.</ref>
<ref name="vtoraya">Аладьев В. З. и др. Персональный компьютер «Искра-226». Архитектура и программное обеспечение: справочное руководство. — Киев, 1988. — структура программного файла и файла данных, значения признака защиты.</ref>
<ref name="vtoraya">Аладьев В. З. и др. Персональный компьютер «Искра-226». Архитектура и программное обеспечение: справочное руководство. — Киев, 1988.</ref>
</references>
</references>


== Источники ==
== Источники ==


* Баласанян В. Э., Богдюкевич С. В., Шахвердов В. А. Программирование на микроЭВМ «Искра 226». — М.: Финансы и статистика, 1987. — 264 с.: ил.
* Баласанян В. Э., Богдюкевич С. В., Шахвердов В. А. Программирование на микроЭВМ «Искра 226». — М.: Финансы и статистика, 1987.
* Реконструкция по образам дисков: файлы <code>TRANSFER</code>, <code>ФС</code> (текстовые), <code>DIG DEM</code>, <code>#СТАТИСТ</code>, <code>ДЕМ6</code> (токенизированные).
* Аладьев В. З. и др. Персональный компьютер «Искра-226». Архитектура и программное обеспечение. — Киев, 1988.
* Таблица глаголов — из прошивки интерпретатора, по материалам проекта [https://github.com/elaranovikova/iskra226 elaranovikova/iskra226].
* [http://www.wang2200.org/disk_org.html Wang 2200 Disk Organization] — файловая система и хеш имени для сопоставления.
* Аладьев В. З. и др. Персональный компьютер «Искра-226». Архитектура и программное обеспечение: справочное руководство. — Киев, 1988.
* Реконструкция по 42 образам дисков: 303 записи каталога, 94 файла программ.
* Структура файловой системы Wang для сопоставления — [http://www.wang2200.org/disk_org.html Wang 2200 Disk Organization].


[[Категория:Искра-226]]
[[Категория:Искра-226]]

Текущая версия от 18:38, 26 августа 2026

Этот документ создан для Emuverse и распространяется на условиях лицензии CC-BY-SA-3.0.

Файловая система Искры 226 — способ хранения файлов на дисках Искра-226. Унаследована от Wang 2200 и совпадает с ней побайтово; содержимое файлов — оригинальное и с Wang несовместимо.

Статья описывает файловую систему, указатель каталога и текстовое представление программ. Отдельно вынесены:

Диск

Физический сектор — 128 байт; 77 дорожек по 26 секторов, одна сторона. Физические сектора попарно объединены в логические по 256 байт со сквозной нумерацией. Далее везде подразумеваются логические сектора. Полный объём тома — 1001 сектор, 256 256 байт.

Типы файлов:

  • ПФ — программный файл: программа на Бейсике в текстовом либо оттранслированном виде;
  • ФД — файл данных.

Файлу выделяется непрерывный диапазон секторов, границы записаны в указателе каталога.

Сектор Содержимое
первый заголовок файла
следующие N поток содержимого
… резерв, нули
последний выделенный концевая запись

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

Диски прямого доступа (запись по абсолютным адресам секторов) указателя каталога не имеют; формат содержимого таких дисков задаёт программа пользователя. Загрузочные диски с интерпретатором имеют собственный формат: нулевой сектор начинается сигнатурой 06 90 09 90 07 90, за ней 18 знаков имени и даты версии.

Указатель каталога

Начинается с сектора 0. Первые 16 байт нулевого сектора — параметры диска:

Смещение Размер Значение
0–1 2 размер указателя каталога в секторах (LS), старший байт первым
2–3 2 текущий конец каталога — первый свободный сектор
4–5 2 конец области каталога
6–15 10 нули

Размер указателя задаётся при создании каталога оператором SCRATCH DISK параметром LS=, по умолчанию 24, допустимо 1…255; в дальнейшем не меняется. В нулевом секторе помещается 15 записей, в остальных 16. Неиспользованные записи заполнены нулями.

Записи не сгруппированы в начале указателя и не упорядочены по секторам файлов: номер сектора, в который попадает запись, вычисляется хешированием имени. Для чтения каталога надо пройти все его секторы, пропуская нулевые записи.

Хеш имени файла

Номер сектора указателя вычисляется по «старому» хешу Wang 2200:

имя дополнить пробелами до восьми байт
tmp = 0
для каждого байта имени:  tmp = tmp XOR байт
tmp = 3 × tmp
tmp = (tmp mod 256) + (tmp div 256)
сектор = tmp mod LS

Свёртка выполняется исключающим ИЛИ, не сложением. «Новый» хеш Wang, введённый в MVP OS 2.5, на Искре не применяется.

Хеш вырождается при LS, кратном трём: после умножения на 3 и складывания половинок результат всегда кратен трём, поэтому занятыми оказываются только каждый третий сектор указателя. При LS = 24 все записи попадают в секторы 0, 12, 15 и 18.

Запись кладётся в первый свободный слот своего сектора, слоты заполняются подряд от начала. Правило переполнения сектора неизвестно.

Освобождение слота выполняется обнулением первых восьми байт записи; имя при этом остаётся на диске. Оператор SCRATCH запись не обнуляет, а помечает.

Запись каталога

16 байт, совпадает с Wang 2200.

Смещение Размер Значение
0 1 статус, битовое поле; бит 0 — файл вычеркнут
1 1 тип файла: 80 — программа, 00 — данные
2–3 2 первый сектор файла, старший байт первым
4–5 2 последний сектор файла, старший байт первым
6–7 2 не используются
8–15 8 имя файла, дополнено пробелами справа

Наблюдаемые значения статуса: 10 — активна, 11 и 21 — вычеркнута, 00 — свободна. Сравнивать статус на точное равенство нельзя, значим только бит 0. Бит 5 (значение 21) предположительно помечает переименование.

Байт типа не различает текстовое и оттранслированное представление программы: у обоих 80.

Оператор LIST DC выводит типы как P (программный), D (данные), SP и SD (вычеркнутые), что соответствует сочетанию байта статуса и байта типа.[1]

Тип «данные» ничего не говорит о внутреннем устройстве файла: он может содержать как логические записи, так и сырые блоки, записанные оператором DATA SAVE BA.

Пример

 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
10 80 00 31 00 3F 00 00 44 49 47 20 44 45 4D 20
└───┘ └───┘ └───┘       └─────────────────────┘

Активная запись, программа, секторы 49…63, имя DIG DEM.

Размещение файлов

  • Файлы лежат подряд в порядке создания, диапазоны секторов не пересекаются.
  • Место вычеркнутого файла заново не занимается: SCRATCH только помечает запись.
  • Первый файл начинается с сектора LS, сразу за указателем.
  • Поле «текущий конец» равно последнему занятому сектору плюс единица, но обрезается по концу области каталога; при разборе границу надёжнее брать по записям каталога.

Заголовочный сектор

Смещение Значение
0 01
1–8 имя файла, дополнено пробелами
9 признак формата записи
10–255 нули

Байт 9 (в справочнике[2] назван «признак защиты») — битовое поле, единственный признак, различающий два представления программы: бит 0 — программа оттранслирована (параметр T оператора SAVE DC), бит 2 — защищена (параметр P); оба вместе соответствуют параметру G.

Значение Символ Защита Представление
20 пробел нет текстовое
21 ! нет оттранслированное
24 ¤ есть текстовое
25 % есть оттранслированное

Значения 22 и 23 не используются. Текстовое представление — режим по умолчанию, оттранслированное включается явным параметром T.

Защищённая программа после загрузки может только выполняться; режим снимается оператором CLEAR.

Секторы потока

Первые два байта каждого сектора программного потока — служебные, в содержимое не входят. У секторов файла данных служебный заголовок занимает один байт.

Байт 0 — позиция сектора:

Код Смысл
02 первый сектор потока
03 последний сектор потока
1C концевая запись
8B запись целиком в одном секторе (только файлы данных)
8F промежуточный сектор

В оттранслированных программах все секторы потока идут с маркером 02. Позиционная разметка 02/8F/03 наблюдается в текстовых файлах и в потоках данных.

Байт 1 программных секторов равен 80. Как признак «программа или данные» он непригоден: у секторов данных на позиции 1 стоит первый байт идентификатора значения. Надёжные признаки — байт 9 заголовочного сектора и байт типа записи каталога.

Концевая запись

1C <длина: 2 байта, старший первым>

Остаток сектора — нули. Соответствует по роли байту 20 в Wang.

Счётчик равен собственной позиции записи от начала файла, считая с единицы, то есть числу занятых секторов вместе с заголовком. Он же — графа «Использовано» в выдаче LIST DC.

  • У программных файлов концевую запись пишет сам оператор SAVE DC; она есть всегда.
  • У файлов данных её пишет прикладная программа оператором DATA SAVE DC END. Если признак конца не записан, в графе «Использовано» стоит 00001.
  • Оператор DATA SAVE DC OPEN пишет в последний сектор файла запись 1C 00 01 — единственный случай, когда счётчик не равен позиции.

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

Счётчик — не инвариант файловой системы и при разборе ненадёжен: у файлов, записанных не операторами DATA SAVE DC, он произволен. Границы файла следует брать из каталога.

Текстовое представление

Программа хранится плоским текстом. Кодировка — КОИ-8 (ГОСТ 19768-74): прописная кириллица в E0–FF, строчная в C0–DF. Номера строк записаны обычными цифрами.

  • Разделитель строк — байт 85.
  • Строка не пересекает границу сектора; хвост сектора заполняется нулями.
  • Байт 24 ($) отображается на экране Искры как ¤.

Байт 85 свободен потому, что диапазон 80–9F в КОИ-8 не занят. Тем же байтом машина разделяет строки в символьном буфере операторов SAVE и LOAD и выдаёт нажатие клавиши CR/LF.

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

Пример

02 80 35 20 52 45 4D 20 F0 E5 F4 F2 E5 EE EB EF … 85 38 20 50 52 49 4E 54 …

Заголовок сектора, затем 5 REM ПЕТРЕНКО …, разделитель, 8 PRINT ….

Виды дисков

Вид Признак
с каталогом байты 0–1 нулевого сектора — разумный LS, дальше 16-байтовые записи
загрузочный сектор 0 начинается с 06 90 09 90 07 90
пакет ассемблера сектор 0 начинается с 7E E1 F3 ED E2 (~АСМБ)
прямого доступа каталога нет, есть заголовочные секторы 01 <имя> <признак>
пустой нули

Отличия от Wang 2200

Wang 2200 Искра-226
Запись каталога 16 байт совпадает побайтово
Хеш имени «старый» и «новый» только «старый»
Маркер концевой записи 20 1C
Маркер заголовка 40 (50 для защищённых) 01
Маркеры секторов битовое поле в старшей тетраде отдельные значения 02/8F/03
Представление программы ключевые слова в токенах, остальное ASCII несовместимо, см. Оттранслированное представление BASIC 02

Совпадает только уровень файловой системы. Инструментарий Wang для разбора самих программ непригоден.

Примечания

  1. ↑ Баласанян В. Э., Богдюкевич С. В., Шахвердов В. А. Программирование на микроЭВМ «Искра 226». — М.: Финансы и статистика, 1987. — 264 с.: ил.
  2. ↑ Аладьев В. З. и др. Персональный компьютер «Искра-226». Архитектура и программное обеспечение: справочное руководство. — Киев, 1988.

Источники

  • Баласанян В. Э., Богдюкевич С. В., Шахвердов В. А. Программирование на микроЭВМ «Искра 226». — М.: Финансы и статистика, 1987.
  • Аладьев В. З. и др. Персональный компьютер «Искра-226». Архитектура и программное обеспечение. — Киев, 1988.
  • Wang 2200 Disk Organization — файловая система и хеш имени для сопоставления.
  • Реконструкция по 42 образам дисков: 303 записи каталога, 94 файла программ.