В предыдущий раз пришлось уделить внимание и бегло рассмотреть работу с файлами в ОС CP/M. А так как «Быстро, хорошо не бывает» (с) было принято решение о необходимости подробного и основательного разбора данного вопроса, так что бы в будущих статьях не тратить на него время и место.
Статья была опубликована в 2020 году в 28 номере журнала по ZX Spectrum'у "ЗаRulem Печатное Слово".
Статья написана в соавторстве с Вадимом Чертковым.
Работа с файлами в ОС CP/M ведется через систему команд Базовой Дисковой Операционной Системе (БДОС). Это аппаратно-независимый модуль, обеспечивающий вместе с Базовой Системой Вода/Вывода (БСВВ) взаимодействие оператора с системой и управление ресурсами системы, прежде всего файлами. БДОС – логическое ядро ОС, которое с помощью механизма вызова системных функций создаёт стандартную среду для транзитных (запускаемых пользователем) программ.
Подробно о ОС CP/M в реализации для компьютера «Profi» и её компонентах, включая все команды БДОС, можно прочитать в брошюре фирмы KRAMIS «Описание операционной системы SP-DOS» (83 стр.). К сожалению, год издательства и иные реквизиты не указаны. Известно о двух изданиях данной брошюры, отличающихся обложками, но полностью идентичных по содержанию, даже опечатки на тех же местах. Брошюру в оригинальном виде в формате PDF можно скачать по ссылкам в конце статьи. Так же там имеется ссылка на незначительно доработанную версию брошюры. В частности всем операциям БДОС были присвоены символьные имена и для удобства добавлено два приложения. В дальнейшем ссылаться будем на доработанную версию брошюры.
В данной статье будут затронуты только вопросы работы с файлами.
Файловая система ОС обеспечивает автоматическое распределение и учёт места в оглавлении и области данных при создании и расширении файла, а так же при его удалении. В случае возникновения аварийных событий файловая система возвращает условие ошибки. Таким образом, пользователю не требуется вникать в организацию диска.
Файловая система ОС обеспечивает четыре вида операций:
Доступ к файлам. Они включают операции создания нового файла, открытия и закрытия существующего файла, чтения из файла и записи в файл. Операции чтения и записи обеспечивают доступ к файлу в последовательном или произвольном режимах. Обмен данными осуществляется 128-байтными блоками, называемыми в дальнейшем «записями». Операции открытия и создания файла обеспечивают файловой системе доступ к файлу, а операция закрытия обеспечивает необходимые корректировки в оглавлении для отображения текущего состояния файла.
Доступ к оглавлению. Они включают операции поиска имени файла в оглавлении, переименования файла, удаления файлов, установки атрибутов файла, вычисления размера файла. Из всех этих операций только операции поиска и удаления файлов допускают использование неявных имен.
Доступ к дискам. Они включают операции выбора диска, сброса диска, изменения состояния диска и определения свободного места на нем.
Смешанные операции. Смешанные операции включают операции установки адреса прямого доступа для обмена с диском, установки кода пользователя, загрузки новой программы, доступа к операциям БСВВ и расширенной БДОС, а также доступа к системным переменным в БУС.
Система поддерживает от 1 до 16 логических дисков. Максимальный размер дискового файла - 8 Мбайт.
Область оглавления диска содержит от 1 до 16 блоков (действительное число задается в БСВВ), размещаемых в начале диска. В этой области содержатся элементы оглавления для каждого файла, в которых определены те блоки в области данных, которые принадлежат данному файлу.
Область оглавления логически разделена на 16 независимых оглавлений (USER) для каждого из 16 возможных пользователей 0-15. В каждый текущий момент времени только одна область пользователя доступна вызывающей программе на всех дисках системы. Эта область может быть изменена вызовом операции БДОС 32 (получение/установка кода пользователя). Область пользователя с кодом 0 имеет в CP/M особое значение. Файловая система обеспечивает открытие файлов в режиме только для чтения в этой области (если указанный файл имеет установленный системный атрибут) в том случае, если в текущей области пользователя указанный файл отсутствует. Это позволяет использовать программы с системным атрибутом, находящиеся в области пользователя 0 на системном диске из любой области пользователя, поэтому нет необходимости хранить их в каждой области пользователя.
Файловая система ОС не поддерживает каталоги, но их роль могут выполнять как раз области пользователей (USER’ы). Изначально это была попытка организации множественного доступа к информации на диске, когда у каждого пользователя был номер (от 0 до 15) и он имел доступ только к файлам в своей области (и к системным файлам в области USER 0). В настоящее время области пользователя (USER’ы) можно рассматривать как заранее созданные каталоги с предопределенными именами USER 0-15, без возможности их изменения. Что конечно не очень удобно, но все-таки лучше, чем единый общий каталог.
Каждый файл в оглавлении идентифицируется именем, состоящим из собственно имени, (восемь символов) и типа файла (три символа). Все операции ОС с файлами определяют запрашиваемый файл по его имени и типу. Некоторые операции файловой системы обеспечивают с помощью неявных имен доступ к нескольким файлам. Неявное имя содержит один или несколько символов «?», которые указывают на совпадение с любым символом в данной позиции. Таким образом, если в имени и типе все символы «?», это означает совпадение со всеми файлами в оглавлении с текущим кодом пользователя.
Имена файлов записываются в оглавлении с использованием латинских букв верхнего регистра и других символов, не являющихся ограничителями (таблица 1) или управляющими символами.
Символы «???» и «?*?» также не должны содержаться в именах файлов, записанных в оглавлении, так как они используются для создания неявных имен. Операция подготовки БУФ при обнаружении в имени или типе файла символа «*» заполняет остаток имени или типа символами «?», формируя, таким образом, неявное имя.
Описанные выше условия работы с именем файла справедливы только в случае подготовки БУФ (Блока Управления Файлом, о нём чуть ниже) средствами БДОС (операция 152), если же БУФ готовиться самостоятельно, то следовать указанным соглашениям не обязательно. Однако при необходимости получить доступ к такому файлу средствами БДОС (например, из командной строки), эти соглашения должны использоваться. В противном случае интерпретатор команд не найдет в оглавлении файл, если в его наименовании используются символы нижнего регистра. Беря это во внимание, очень рекомендуется придерживаться указанного соглашения.
Символ |
Код |
Нуль |
00h |
Пробел |
20h |
CR |
0Dh |
Табуляция |
09h |
: (двоеточие) |
3Ah |
; (точка с запятой) |
3Bh |
= (знак равно) |
3Dh |
^ (знак карет) |
5Eh |
. (точка) |
2Eh |
[ (открывающая прямоугольная скобка) |
5Bh |
] (закрывающая прямоугольная скобка) |
5Dh |
< (открывающая угловая скобка) |
3Ch |
> (закрывающая угловая скобка) |
3Eh |
, (запятая) |
2Ch |
Таблица 1. Ограничители имени файла
Каждый файл состоит из 128-байтовых записей. Позиция каждой записи определяется номером произвольного доступа записи. Для файлов создаваемых последовательно, первая запись имеет позиции 0 и последняя - позицию, на одну меньше, чем число записей в файле.
Файл, который создавался с произвольным доступом, может иметь "дыры", если соответствующие записи не были произведены. К такому файлу может быть только произвольный доступ и недопустимо его последовательное чтение.
Работа с файлами осуществляется посредством Блока Управления Файлом (БУФ).
БУФ - это структура данных, которая организуется и инициализируется транзитной программой, а также используется файловой системой при доступе к файлам через оглавление. Все операции с файлами обращаются за исходной информацией к БУФ. Система хранит текущее состояние файла в БУФ во время исполнения файловых операций. Кроме того, операции произвольного доступа используют 3 байта, следующие за БУФ, для определения номера произвольной записи.
При вызове операций, осуществляющих доступ к файлам или оглавлению, регистровая пара DE должна содержать адрес БУФ, указывающего на файл или файлы, с которыми должна производится операция. Для большинства операций длина БУФ равна 33 байт, а для операций произвольного доступа, вычисление размера файла и свободного места на диске размер БУФ равен 36 байт (таблица 2). Число одновременно созданных БУФ, а значит и число рабочих файлов, ограничено только объёмом свободной памяти и здравомыслием программиста.
где:
байт 0: |
ДС |
Код диска (0-16) 0- выбор текущего диска 1- выбор диска A 2- выбор диска B --- 16- выбор диска P |
байты 1-8: |
И1...И8 |
Содержат имя файла в символах верхнего латинского регистра. Старшие биты позиций И5-И8 могут использоваться системой и не должны использоваться прикладной программой. Старшие биты позиций И1-И4 могут использоваться прикладной программой для внутренних атрибутов. |
байты 9-11: |
Ф1...Ф3 |
Содержат тип файла в символах верхнеголатинского регистра. Старшие биты этих позиций используются системой для атрибутов файла и не должны использоваться прикладными программами в других целях; |
|
Ф1'=1 |
(старший бит байта Ф1) обозначает файл R (только для чтения); |
|
Ф2'=1 |
(старший бит байта Ф2)обозначает файл типа S (системный); |
байт 12: |
3К |
Содержит номер текущего экстента (USER’а), обычно устанавливается в 0 вызывающей программой. Может изменяться от 0 до 31 в процессе обмена с файлом; |
байт 13: |
С1 |
Счетчик байтов (число записей в последней записи файла). Должен устанавливаться прикладными программами; |
байт 14: |
С1 |
Резервируется для системы; |
байт 15: |
СЧ |
Счетчик записей для экстента "3К". Принимает значения от 0 до 128; |
байты 18-31: |
В0-ВN |
Резервируются для системы. Содержат номера блоков, занимаемых файлом; |
байт 32: |
Т3 |
Текущая запись для обмена с файлом в последовательном режиме. Обычно должна устанавливаться в 0 вызывающей программой при создании или открытии файла; |
байты 33-35: |
R0,R1,R2 |
Номер произвольной записи в пределах 0-65535. Используется только в произвольном режиме доступа к файлу младший байт R0, старший - R1, байт R2 содержит признак переполнения |
Для операций доступа к оглавлению вызывающая программа перед вызовом операции должна инициализировать байты 0-11 БУФ.
Операция переименования файла требует, чтобы новое имя было помещено в байты 17-27 БУФ.
Перед вызовом операций открытия и создания файла вызывающая программа должна инициализировать байты 0-12 БУФ. Обычно байт 12 устанавливается в 0.
Кроме того, если работа с файлом будет осуществляться с начала файла в последовательном режиме, то перед началом работы байт 32 (ТЗ) должен быть установлен в 0.
После того, как БУФ активизирован операцией открытия или создания файла, программа не должна модифицировать его. Исключение составляют байты 33-35 (R0,R1,R2), в которых программа может устанавливать номер произвольной записи для режима произвольного доступа.
Необходимо подчеркнуть, что при записи в файл информация о выделенных файлу блоках данных на диск не записывается. Это делается только при исполнении операции закрытия файла. Поэтому необходимо, чтобы программа, изменяющая содержимое файла, обязательно вызывала операцию закрытия файла, иначе данные в файле будут потеряны.
Старшие биты файла (И1',...И8') и типа файла (Ф1',...Ф3') БУФ содержат атрибуты файла; при этом значение 1 соответствует булевскому true (истина) и 0 - false (ложь).
Значения атрибутов следующие:
Ф1: |
Атрибут "только для чтения" |
при этом значению 1 соответствует "только для чтения" (read: R), а 0 - для записи (write: W) и чтения. |
Ф2: |
Системный атрибут. |
Файлы с этим атрибутом в области пользователя 0 доступны из любой области пользователя в режиме "только для чтения" с системного диска (диска A:), при этом значению 1 соответствует "системный" (system: S), а значению 0 "несистемный" (directory: D). |
И1',...,И4' |
Атрибуты пользователя |
Могут определяться пользователем. |
И5',...,И8' |
Интерфейсные атрибуты |
используются системой и не могут использоваться как атрибуты файла. |
Таблица 3. Атрибуты файла.
CP/M может обеспечить обмен несколькими записями с диском за одну операцию БДОС. Этот процесс называемый мультиселекторным обменом, удобно использовать при операциях обмена, когда размер физической записи больше 128 байт.
Количество записей, которое может участвовать в мультиселекторном обмене, изменяется в пределах от 1 до 128. Это значение устанавливается операцией БДОС 44 (установка мультиселекторного счетчика). Значение мультиселекторного счетчика определяет количество секторов, участвующих в обмене, для операций последовательного и произвольного обмена (операции 20, 21, 33, 34 и 40). Если значение мультиселекторного счетчика равно N, то вызов одной из указанных выше операций эквивалентен N последовательным вызовам при обмене по одному сектору. Если операция прерывается по ошибке (например, при достижении конца файла), Файловая система возвращает в регистре H количество записей, с которыми успешно осуществился обмен.
При работе с файлами БДОС обнаруживает физические и логические ошибки и выдает на консоль сообщения об этих ошибках. Сообщение об ошибках подробно описаны в брошюре фирмы KRAMIS «Описание операционной системы SP-DOS», так что мы не будем сейчас на них останавливаться.
С адреса 0 (0000h) по адрес 255 (00FFh) в CP/M расположена базовая страница памяти. Она так же хорошо описана в брошюре фирмы KRAMIS «Описание операционной системы SP-DOS», но сейчас важно упоминать, что если в программу были переданы параметры, то в области 1 БУФ (005Ch - 006Bh) подготавливается БУФ из первого имени файла из параметров, а в области 2 (006Ch - 007Bh) из второго имени. Если в параметрах команды имена файлов не указаны, то соответствующие поля заполняются пробелами.
Буфер ПДП по умолчанию с адреса 80h заполняется остатком параметрами команды, при этом в первый байт заносится количество символов остатка, а в последующие сам остаток. В буфере прямого доступа остаток ограничивается нулевым байтом. Так как файловая система использует вторую часть БУФ и буфер ПДП для дисковых операций, прикладные программы перед вызовом операций БДОС должны сохранить информацию, занесенную в них интерпретатором команд.
В БДОС реализован целый набор операция по работе с файлами (таблица 3). Мы не будем рассматривать их все, так они хорошо описаны в брошюре от KRAMIS, номера страниц приведены в этой брошюре. На практике чаше всего необходимо производить чтения данных из файлов вот давайте и разберем, как эта задача решается в CP/M. Все примеры кода можно найти на прилагаемом образе диска.
Имя операции |
Код |
Описание |
№ страницы |
|
Стандартные операции | ||||
bdReset |
13 |
0Dh |
Сброс дисковой системы |
39 |
bdDisk |
14 |
0Eh |
Выбор диска |
39 |
bdOpen |
15 |
0Fh |
Открытие файла |
40 |
bdClose |
16 |
10h |
Закрытие файла |
42 |
bdSearch |
17 |
11h |
Поиск первого файла |
43 |
bdSearch2 |
18 |
12h |
Поиск следующего файла |
44 |
bdDel |
19 |
13h |
Удаление файла |
44 |
bdReadCon |
20 |
14h |
Последовательное чтение |
45 |
bdWriteCon |
21 |
15h |
Последовательная запись |
47 |
bdCreate |
22 |
16h |
Создание файла |
48 |
bdRenem |
23 |
17h |
Переименование файла |
49 |
bdDiskVec |
24 |
18h |
Получение вектора состояния дисков |
50 |
bdDiskCur |
25 |
19h |
Получение текущего диска |
50 |
bdPDPInst |
26 |
1Ah |
Установка адреса буфера ПДП |
51 |
bdDistVec |
27 |
1Bh |
Получить адрес вектора распределения |
51 |
bdProtect |
28 |
1Ch |
Установка защиты записи |
52 |
bdProtVec |
29 |
1Dh |
Получение вектора защиты записи |
52 |
bdAttrSet |
30 |
1Eh |
Установка атрибутов файла |
52 |
bdDiskPar |
31 |
1Fh |
Получение адреса блока параметров диска |
54 |
bdUser |
32 |
20h |
Получение/установка кода пользователя |
54 |
bdReadRnd |
33 |
21h |
Произвольное чтение |
54 |
bdWriteRnd |
34 |
22h |
Произвольная запись |
56 |
bdSize |
35 |
23h |
Получение размера файла |
58 |
bdRecRnd |
36 |
24h |
Установка номера произвольной записи |
59 |
bdDiskRes |
37 |
25h |
Сброс диска |
60 |
bdReadRnd0 |
40 |
28h |
Произвольная запись с заполнением нулями |
61 |
bdMultCount |
44 |
2Ch |
Установка мультиселектороного счётчика |
61 |
bdErr |
45 |
2Dh |
Установка режима обработки ошибок |
62 |
bdDiskFree |
46 |
2Eh |
Получение свободного места на диске |
62 |
bdBSVV |
50 |
32h |
Вызов операции БСВВ или операции расширенной БДОС |
66 |
bdBUFCreate |
152 |
98h |
Подготовка БУФ |
72 |
Операции расширенной БДОС | ||||
|
50/129 |
32h/81h |
Обмен с файлом |
74 |
|
50/130 |
32h/82h |
Обмен с диском |
75 |
Таблица 4. Список операций БДОС связанных с работой с файлами
В качестве приложения к статье идет образ диска в формате «PRO». Его отлично распознают эмуляторы «ZXMAK2» (https://archive.codeplex.com/?p=zxmak2) и «UNREAL SPECCY» (https://sourceforge.net/projects/unrealspeccy/). Под ОС Windows с образом диска можно работать через программу «Stein Blume» (https://zx-pk.ru/threads/26454-steinblume-cp-m-disk-image-explorer-(ex-atm-cp-m-explorer).html). А записать на реальную дискетку образ можно через программу «ZX Disk Studio» (https://zx-pk.ru/threads/12842-zx-disk-studio-programma-dlya-raboty-s-obrazami-diskov.html).
Образ диска системный с установленным файловым менеджером «Hop Commander 1.03». Для просмотра и редактирования текстовых файлов с примерами кода имеется текстовый редактор «Write 3». Загрузить текст в него можно как из самого редактора, так и из файлового менеджера по клавише «F4» или последовательной комбинации клавиш «2»+«E».
Так же на диске есть ассемблер «m80» и линковщик «l80», которые позволят скомпилировать примеры. Для этого достаточно в файловом менеджере выбрать файлы «*.asm» по «Enter». В результате получиться запускаемый файл «*.COM».
В ходе реализации заданий будем использовать уже знакомые по предыдущим статьям макросы, не буду повторно приводить их код, только коротко опишу. Сам код можно посмотреть в файле «BIOSK.INC» на прилагаемом образе диска.
.writed “значение”, [параметр] – выводит по текущем координатам на экран в десятичном формате 16 битное число 0…65535 или содержимое регистров A, SP, HL, DE, BC, IX, IY. Если выводиться 16 битное число, то в качестве «параметра» необходимо указать «1», противном случае его можно опускать или указывать «0».
Say “текст”, [регистр] – выводить «текст» по текущим координатам на экран, если указан один из следующих регистров A, SP, HL, DE, BC, IX, IY, то его значение в десятичной форме будет непечатно сразу за «текстом».
pause - ждет нажатия любой клавиши, если нажата «Esc», то производит холодный рестарт системы (то есть выход из текущей программы), а по любой другой продолжает выполнение программы.
.push <регистровые пары>/.pop <регистровые пары> - позволяют одной командой занести или снять со стека сразу несколько регистровых пар. Передаваемый список регистровых пар, должен быть в угловых кавычках и разделяться запятой. Пример: .push <hl, de> … .pop <de, hl>
.bdos “операция”, [параметр] – вызов «операции» БДОС, с передачей «параметра».
Для визуализации действий будем выводить на экран ту информацию, которую загружаем из файла. Для этого будем работать с текстовым файлом. Так как в одном секторе 128 байт, в него помещаться 2 строки текста по 64 символов строке. Создадим текстовый файл «TEST.TXT» и пропишем в каждых 2 строках номер сектора, в котором находится эти строки.
Теперь всё готово к решению практических задач.
Задание 1. Подготовка БУФ средствами БДОС и в два этапа последовательно прочитать три сектора.
Заголовок всех листингов будет состоять из трех строчек.
.Z80 ; Указываем, что будем работать в мнемониках процессора z80
org 100h
INCLUDE BIOSK.INC ; Загружаем описание макросов
;----------------------------------------------------------------
Теперь создадим БУФ для работы с файлом. Для чего воспользуемся операцией БДОС 152 (bdBUFCreate). «Подготовка БУФ». Она готовит БУФ из имени файла. При её вызове в регистровой паре DE должен передаваться адрес блока подготовки имени файла (PFCB), имеющего следующий формат
PFCB: DW STRING ;адрес имени файла
DW AFCB ;адрес подготавливаемого БУФ
Имя файла должно задаваться в следующем виде:
[D:]Имя файла[.тип файла]
где поля в квадратных скобках необязательны.
Соответственно в конце листинга добавляем строки с массивами исходных данных:
;======================================================================
; Информационные сообщения
err01: db '<!> File not found! <!>', '$'
info01: db '<.> Read 1 sector', 0dh, 0ah, '$'
info02: db '<.> Read 2-3 sectors', 0dh, 0ah, '$'
;======================================================================
FileName: db 'TEST.TXT', 0 ; Имя рабочего файла
PFCB: dw FileName ; Ссылка на имя рабочего файла
dw FCB_file ; Ссылка на БУФ рабочего файла
FCB_file: ds 36 ; Блок управления файлом.
PDP_file: ds 128*2 ; Буфер файла для загрузки данных с диска.
Теперь продолжим решение поставленной задачи.
.bdos bdBUFCreate,PFCB ; Создаем БУФ для рабочего файла.
.bdos bdPDPInst, PDP_file; Устанавливаем адрес буфера файла.
.bdos bdOpen, FCB_file; Открываем файл.
inc a ; if a=255 Если на диске нет такого файла.
jp z, err.nofile ; then Процедуру обработки ошибки рассматривать не будем.
По умолчанию в CP/M маркером конца текста для вывода на экран является знак «$». Ставим его за буфером файла.
ld a, '$' ; Маркер конце текста.
ld (PDP_file+128+1), a ; Маркируем конец буфера файла.
Выводим информационную строку о том, какие сектора читаем.
.bdos bdWrite, info01
Выполняем чтение первого сектора и выводим на экран то, что прочитали.
.bdos bdReadCon, FCB_file ; Последовательное чтение 1 сектор.
.bdos bdWrite, PDP_file ; Вывод прочитанного на экран.
pause
Так как на следующем этапе нужно будет читать два сектор за обращение, переносим маркер конца текста.
ld a, '$' ; Маркер конце текста.
ld (PDP_file+128*2+1), a ; Переносим маркер конца буфера файла.
Завершаем выполнение задачи.
.bdos bdWrite, info02
.bdos bdMultCount, 2 ; Мультисекторный счетчик =2
.bdos bdReadCon, FCB_file ; Последовательное чтение 2-3 секторов
.bdos bdWrite, PDP_file ; Вывод прочитанного на экран.
pause
После компиляции и запуска полученного кода на экране мы увидим следующее:
Задание 2. Подготовка БУФ вручную и в два этапа произвольно прочитать пять секторов.
Как видно из предыдущей задачи подготовить БУФ средствами БДОС не сложно. Но вручную это сделать иногда ещё проще. Для решения задачи 2, в конце листинга, в блоке данных, размещаем ручное описание БУФ:
; Блок управления файлом.
FCB_file: db 0 ; ДС Код диска 0-16. 0- текущий диск
;12346578
db 'TEST ' ; И1-И8 Имя файла
db 'TXT' ; Ф1-Ф8 Расширение файла
db 0 ; ЗК Номер экстента 0-31
db 0 ; C1 Счётчик байтов
ds 18 ; <!> Не менять
db 0 ; ТЗ Текущая запись
ds 3 ; R0-R2 Номер произвольной записи
Теперь просто опускаем вызов операции БДОС 152 (bdBUFCreate). «Подготовка БУФ», так как БУФ уже подготовили, остальное без изменений.
.bdos bdPDPInst, PDP_file ; Устанавливаем адрес буфера файла.
.bdos bdOpen, FCB_file ; Открываем файл.
inc a ; if a=255 Если на диске нет такого файла.
jp z, err.nofile ; then
Начнём выполнение задания с чтения трёх секторов. Предварительно устанавливаем маркер конца данных:
ld a, '$' ; Маркер конце текста.
ld (PDP_file+128*3+1), a ; Маркируем конец буфера файла.
Для включения произвольного доступа к файлу вызываем операций БДОС 36 (bdRecRnd) «Установка номера произвольной записи». В результате выполнения, которой в полях R0...R2 БУФ файла будет записан номер произвольной записи, следующий за записью, доступ к которой осуществляется в последний раз. Эта же операция переводит файл в режим произвольного чтения.
.bdos bdRecRnd, FCB_file ; Включаем произвольный режим доступа к файлу.
Теперь в поля R0..R1 заносим номер сектора с которого хотим начать чтение. Пусть, в нашем случае, это будет 7 сектор.
ld hl, 7 ; Устанавливаем сектор для произвольного чтения.
ld (FCB_file+33), hl ;
Далее действуем по схеме из задания 1, только вместо операции БДОС 20 (bdReadCon) «Последовательное чтение» используем операцию 33 (bdReadRnd) «Произвольное чтение».
.bdos bdMultCount, 3 ; Мультисекторный счетчик =3
.bdos bdWrite, info01
.bdos bdReadRnd, FCB_file ; Произвольное чтение 3-х секторов.
.bdos bdWrite, PDP_file ; Вывод прочитанного на экран.
pause
Читаем и выведем 3 и 4 сектора.
ld a, '$' ; Маркер конце текста.
ld (PDP_file+128*2+1), a ; Переносим маркер конца буфера файла.
ld hl, 3 ; Устанавливаем сектор для произвольного чтения.
ld (FCB_file+33), hl ;
.bdos bdWrite, info02
.bdos bdMultCount, 2 ; Мультисекторный счетчик =2
.bdos bdReadRnd, FCB_file ; Произвольное чтение 2-х секторов
.bdos bdWrite, PDP_file ; Вывод прочитанного на экран.
pause
Скомпилировав и запустив программу, получим на экране следующий результат.
Задание 3. Переход от произвольного режима чтения к последовательному.
При решении предыдущей задачи был рассмотрен переход от последовательного к произвольному чтению. На практике встречаются случаи, когда необходимо обратный переход к последовательному режиму. Давайте посмотрим, как это можно сделать.
Прямой команды, на подобии операции БДОС 36 (bdRecRnd) «Установка номера произвольной записи» для реализации этой задачи нет. Если сразу после произвольного чтения, начать последовательное чтение, то первым прочитается последний прочтённый в предыдущий раз сектор. Например: в произвольном режиме были прочтены сектора 3, 4, 5, если сразу начать последовательное чтение, то будет прочтены сектора 5, 6, 7. Чтобы нивелировать данную ситуацию случае нужно сделать следующее, когда:
необходимо продолжать последовательное чтение с текущей позиции в файле, нужно: установить мультиселекторный счётчик на 1, произвести техническое последовательное чтение одного сектора, после чего установить желаемое значение мультиселектороного счётчика и продолжить последовательное чтение.
необходимо начать последовательное чтение с новой позиции в файле, нужно: установить в полях R1-R2 БУФ номер сектор, с которого необходимо производить чтение, так же установить мультиселекторный счётчик на 1, произвести техническое произвольное чтение, вернуть нужно значение мультиселекторному счётчику и начать последовательное чтение.
Как видно, ни чего сложного, хотя действий и больше чем при переходе к произвольному режиму чтения. Напишем код для примера, взяв за основу код от задачи 2, так как в нём уже есть переход к произвольному режиму чтения.
Предыдущее задание закончилось на том, что мы прочитали сектора 3, 4. Теперь последовательно прочитаем сектора 5, 6 а затем 7. Переходим в режим последовательного чтения.
.bdos bdMultCount, 1 ; Мультисекторный счетчик =1
.bdos bdReadCon, FCB_file ; Техническое последовательное чтение 1-го сектора.
.bdos bdMultCount, 2 ; Мультисекторный счетчик =2
Читаем и выводим сектора 5, 6.
.bdos bdWrite, info03
.bdos bdReadCon, FCB_file ; Последовательное чтение 2-х секторов
.bdos bdWrite, PDP_file ; Вывод прочитанного на экран.
pause
Теперь прочитаем 7 сектор.
.bdos bdMultCount, 1 ; Мультисекторный счетчик =1
ld a, '$' ; Маркер конце текста.
ld (PDP_file+128+1), a ; Переносим маркер конца буфера файла.
.bdos bdWrite, info04
.bdos bdReadCon, FCB_file ; Последовательное чтение 1-го секторов
.bdos bdWrite, PDP_file ; Вывод прочитанного на экран.
pause
Теперь прочитаем сектор 10, а затем сектор 11. Смещаемся в файле на 10 сектор.
.bdos bdRecRnd, FCB_file ; Включаем произвольный режим доступа к файлу.
ld hl, 10 ; Устанавливаем сектор для произвольного чтения.
ld (FCB_file+33), hl ;
.bdos bdReadRnd, FCB_file ; Техническое произвольное чтение 1-го секторов.
Читаем его.
.bdos bdWrite, info05
.bdos bdReadCon, FCB_file ; Последовательное чтение 1-го секторов
.bdos bdWrite, PDP_file ; Вывод прочитанного на экран.
pause
Последовательно читаем 11 сектор.
.bdos bdWrite, info06
.bdos bdReadCon, FCB_file ; Последовательное чтение 1-го секторов
.bdos bdWrite, PDP_file ; Вывод прочитанного на экран.
pause
Собственно, всё. Компилируем, запускаем и видим такую картину.
Статьи, графика – это все очень хорошо и полезно. Но в современном мире есть еще один способ передачи информации, который мы пока обходили стороной - я говорю о видео роликах. Не смотря на то, что этот способ имеет, целый ряд недостатков, он же обладает и некоторым набором плюсов. Поэтому было, приятно решения попробовать себя в этом направлении. Для чего был создан YouTube канал «Зазеркалье».
Компьютерщик, не совсем обычный человек. Жизнь его состоит из двух частей, и грань раздела проходит по стеклу монитора. Одна часть находится в реальном мире, а вторая в удивительной стране - Зазеркалье. И сложно сказать какая из частей главнее. Канал посвящен всем аспектам жизни по ту сторону монитора, в Зазеркалье. В первую очередь он будет отражать те грани этого мира, которые интересны нам, это: и ZX Spectrum, и OS/2, и различный языки программирования, и многое другое. Но мир Зазеркалья гораздо многограннее, так что если у кого-то вдруг появиться желание отразить интересные ему грань, будем рады предоставить эту площадку. Сложно надеяться на частый выход видео, но точно они будут - это однозначно.
На канале «Зазеркалье» выложено видео работы программ приведенных в заданиях. Ссылки на него можно найти в приложении.
С остальными аспектами работы с файлами, не сложно разобраться по аналогии, рамки статьи не позволяют уделить им время. Читайте брошюру фирмы KRAMIS «Описание операционной системы SP-DOS», там есть вся необходимая информация. Если все-таки останутся вопросы, с нами можно связаться по адресам:
FidoNet: Tarasow Aleksey 2:5053/57
E-mail: tae1980(очень злая собака)yandex.ru
А так же много материала форуме и в группе ВК.
Группа поддержки компьютера Profi: https://vk.com/profi1024
Группа поддержки компьютера Profi: https://t.me/Profi1024
YouTube канал «Зазеркалье» https://www.youtube.com/@user-lw7ey5yu1e
Приложение:
Брошюра фирмы KRAMIS «Описание операционной системы SP-DOS» (83 стр.) в оригинальном виде (PDF). Яндекс Диск: https://yadi.sk/i/_rOMRjzHXxYV5Q ВК: https://vk.com/doc359059980_542730849
Брошюра фирмы KRAMIS «Описание операционной системы SP-DOS» с доработками (PDF). Яндекс Диск: https://yadi.sk/i/mDsTcAylayL0SQ ВК: https://vk.com/doc359059980_542730717
Брошюра фирмы KRAMIS «Описание операционной системы SP-DOS» с доработками в формате книги, удобно для печати (PDF). Яндекс Диск: https://yadi.sk/i/BGbKvjjLQA16UQ ВК: https://vk.com/doc359059980_542730575
Архив ReadFile.lzh – с исходными кодами примеров. Яндекс Диск: https://yadi.sk/d/ZOTOk_mOEkOE4w ВК: https://vk.com/doc359059980_542732362
Образ диска ReadFile.pro – загрузочный диск, с исходными кодами примеров. Яндекс Диск: https://yadi.sk/d/WyrEVfmywXMERQ ВК: https://vk.com/doc359059980_542732388
Видео работы заданий приведенных в статье канале «Зазеркалье»: https://youtu.be/l7EH_sKj1pg
Комментарии (8)
Blackfire5020
22.08.2024 09:39А чем вы копируете файлы из тр-доса в CP/M и обратно? Я до сих пор пользуюсь CopyK или хонюком (HC) под эмулем.
Но это всё монстры, а нужна самая простая утилита, которую можно держать на каждом диске. Чтобы позволяла только выбрать файлы на диске-источнике и указать диск-приёмник. Типа from_trd и to_trd в исдосе.
До сих пор никто не написал?tae1980 Автор
22.08.2024 09:39Переброска данных TR-Dos<>CP/M происходит через CopyK. Нового софта нет за ненадобностью. Для тех кто использует CP/M TR-Dos нужен только для игр, по сути нужно один раз забрать от туда данные и всё. Те кто пользуются TR-Dos'ом о CP/M имеют смутные представления, ибо он им не нужен. Середины нет. Вадим Чертков периодически порывается написать что-то подобное для PQ-Dos, но я его отговариваю, так как есть более важные проблемы. PQ-Dos использует fat16, так что проблем с переброской данных с IBM PC, TR-Dos тут не нужен ни как боком. Да чистый CP/M с появлением PQ-Dos постепенно отмирает, за ненадобностью и проблемностью в работе.
Что нужно так это запуск TR-dos программ из CP/M. Этого пока нет, но есть понимание как можно сделать. Постоянно откладывается так как рук не хватает.
Blackfire5020
22.08.2024 09:39Профик есть не у всех. Как этот CopyK запускать на пентагоне или скорпе?
Много лет назад CP/M 2.2 портировали на пентагон/скорпион с экраном 512х192, но как обмениваться файлами ? Например, кто-то в аласме написал программу, надо её скопировать на CP/M диск и запустить. Но нечем. Или есть текст, его надо перекинуть в CP/M, обработать, и вернуть обратно. И опять нечем. Вот о чём речь.
В MOA CP/M есть утилитка setform2 для настройки DPB любого диска на стандарт ATM или MS-DOS, но по непонятным причинам она не работает, как должна. Я лазил внутрь - и ужаснулся. Оно написано на бейсике и откомпилировано.
А PQ-DOS и прочие ни с чем не совместимые поделки - это графоманство и пустая трата сил. Я знал человек 10 в Москве, каждый из которых пытался написать ОС и прославиться. В итоге никто ничего не добился, только зря потратили время. Лучше бы они написали что-то полезное для старой системы.
И насчёт "середины нет" -- отучайтесь говорить за всех. Свой первый Спектрум я купил в 1989 году, и я знал очень много людей, которые как раз из этой середины, которой по вашему нет.tae1980 Автор
22.08.2024 09:39Профик есть не у всех. Как этот CopyK запускать на пентагоне или скорпе?
Это чисто софт под Профи.
Много лет назад CP/M 2.2 портировали на пентагон/скорпион с экраном 512х192
Веду архив и таких версий CP/M. Так что если что есть кдайте.
По вашему вопросу, ни чего сказать не могу. Если есть инструменты работы с MS-Dos дисками, то можно через них. Читал несколько статей, про как люди использовали в работе эти версии CP/M, но подобной информации в них нет.
Оно написано на бейсике и откомпилировано.
Лично я не вижу ни чего плохого в этом. На Паскале, Си писать можно, а на бейсике нельзя? Главное что бы программа решала поставленные задачи. А инструмент реализации вопрос десятый.
А PQ-DOS и прочие ни с чем не совместимые поделки - это графоманство и пустая трата сил.
Честно, после такого - желания общаться с вами нет. Скажите то же самое разработчику Линуксы.
PQ-Dos уже стала почти стандартом для Profi и может быть легко портирована почти на любой клон спекка, а первый версии вышли в 1995 году.
Blackfire5020
22.08.2024 09:39// Так что если что есть кидайте. //
Нашёл у себя загрузочный диск FK0 CP/M, экран 512х192 (timex) или обычный. Она для пентагона с кэшем (через IN #FB) или скорпиона. По формату дисков совместима с MOA CP/M. Это я переделывал много лет назад. Есть исходники, можно прикрутить к ней поддержку профинского экрана. Для этого надо где-то найти 4 Кб (под эмулятор VT-52 и шрифт). Профик вроде позволяет подключать страницы с адреса отличного от #C000 ?
Есть желание что-то сделать для неё, но нечем засовывать файлы внутрь образов. SteinBlume неправильно обрабатывает образы от MOA (перепутано чередование)...
А мы с вами давно заочно знакомы, я комод в фидоэхе zx.spectrum. Бываете на форуме у Юдина?
checkpoint
БУФ это FCB ? Чтож Вы тогда постеснялись системные вызовы на русский перевести ? Ну и название операционной системы ОС УП/М, для полноты картины. ;)
В тему: недавно попалась интересная статья Getting back into C programming for CP/M. Рекомендую.
tae1980 Автор
В литературе для Профи такой перевод используется с начала 90х.
Спасибочки, почитаем.
Но если говорить о Си, то на мой взгляд лучше использовать "Small C". Это кроссплатформенный компилятор есть версию под cp/m, dos, windows, linux. Последнее обновление, если ни чего не путаю, вышло в 2022 году под все системы. Так что под CP/M можно писать и отладить код который спокойно будет работать на современных машинах. :)
checkpoint
В той статье как раз говорится о каком-то древнем Си компиляторе (Aztech C Compiler) с минималистичным синтаксисом для Z80. Этот компилятор генерирует ассемблерный текст который далее нужно ассемблировать и линковать. У компилятора есть фича - ограничить систему команд только набором для i8080.