Nicron #23
06 марта 1997

Программирование - курс изучения ассемблера от Wlodek Black, продолжение. Монозагрузчик.

╔──────────────────────────────────────────────────────────────╗
│ ▒▒▒▒░  ▒▒▒▒░  ▒▒▒▒░ ▒▒▒▒▒▒░▒▒░ ▒▒░▒▒▒▒▒▒░  ▒▒▒▒░▒▒▒▒▒▒░▒▒▒▒▒░│
│▒▒░ ▒▒░▒▒░ ▒▒░▒▒░ ▒▒░▒▒░    ▒▒▒▒▒▒░▒▒░     ▒▒░▒▒░▒▒░    ▒▒░ ▒▒│
│▒▒░ ▒▒░▒▒░    ▒▒░    ▒▒▒▒▒░ ▒▒░ ▒▒░▒▒▒▒▒▒░ ▒▒░▒▒░▒▒▒▒▒░ ▒▒░ ▒▒│
│▒▒▒▒▒▒░▒▒░ ▒▒░▒▒░ ▒▒░▒▒░    ▒▒░ ▒▒░▒▒░ ▒▒░▒▒░ ▒▒░▒▒░    ▒▒▒▒▒░│
│▒▒░ ▒▒░ ▒▒▒▒░  ▒▒▒▒░ ▒▒▒▒▒▒░▒▒░ ▒▒░▒▒▒▒▒▒░▒▒░ ▒▒░▒▒▒▒▒▒░▒▒░z80│
╚──────────────────────────────────────────────────────────────╝

[ Продолжение (по письмам читателей) ]

(C) WLODEK BLACK

			МОНОЗАГРУЗЧИК

...Снова здравствуйте, друзья. Надеюсь, вы еще не стерли  файлы
великой  демы   всех   времен   и   народов    под    названием
"DIGITAL TUNE 1"? Мы возвращаемся к нашим... М-да... Ладно,  мы
просто возвращаемся. В прошлый (точнее,  можно сказать,  в поза-
прошлый...) раз мы добрались до момента, когда перед нашим  взо-
ром предстали 4 файла скомпрессированных данных - по одному для
каждой из страниц 19, 20, 22 и 16. Я паковал LZPAC-ом, и у меня
получились следующие цифры:
dt1.19<		- 4472 байта, 18 секторов;
dt1.20<		- 4812 байт,  19 секторов;
dt1.22<		- 4494 байта, 18 секторов;
dt1.16<		- 6410 байт,  26 секторов.
Я использовал имена для файлов, построенные по принципу: "dt1" -
от слов "digital tune 1"; "19" (также "20", "22", "16") - номер
страницы ОЗУ; "<" - означает, что файл пакованный (то есть"стал
меньше"). Вы, конечно, можете использовать любые  другие  имена.
Все равно в конце концов все  превратится  в  один-единственный
файл.
Давайте теперь сольем эти 4 файла в один.  Загрузите  "dt1.16<"
на адрес 28964, а последующие файлы грузите  вплотную  друг  за
дружкой, то есть "dt1.20<" грузите на адрес 28964+4472,  и  так
далее. Потом выгрузите большой файл:
  SAVE "dt1.<" CODE 28964,20188.
Проверьте: 28964+20188=49152, то есть граница начала  переключа-
емых страниц ОЗУ. В данном случае в памяти  есть  место,  чтобы
принять сразу весь объем упакованных кодов. Потом стартовая про-
грамма "распихает" отдельные куски блока кодов по страницам  19,
20 и 22. Кстати, у нас есть еще упакованная картинка!

		Набор стандартных функций TR DOS.

Для программиста, пишущего на ассемблере,  TR DOS предоставляет
довольно обширный набор так называемых стандартных функций,  вы-
полняющих такие необходимые действия, как работа с файлами и от-
дельно дорожками и секторами - поиск, чтение, запись - и другое.
Полный перечень функций можно найти в любой инструкции к компью-
теру, в которой содержится руководство по пользованию TR DOS,по-
этому здесь я не буду повторяться. Скажу только, что для обраще-
ния к стандартным функциям TR DOS нужно занести  номер  вызывае-
мой подпрограммы в регистр C и совершить CALL #3D13,   предвари-
тельно занеся входные параметры в другие регистры.  Для нас сей-
час представляет интерес функция номер 5 - чтение группы  секто-
ров. Входными параметрами для нее являются начальные трек и сек-
тор и количество считываемых секторов, а также  адрес,  на кото-
рый начинать загружать данные:
DE - начальные трек/сектор (Е - сектор, D - трек);
B  - количество читаемых секторов;
HL - адрес загрузки.
Файловая структура диска в TR DOS очень проста. Файлы располага-
ются на диске по порядку их следования в каталоге. Каждый после-
дующий файл начинается с трека/сектора, идущего за последним се-
ктором текущего файла. Системная переменная TR DOS, находящаяся
по адресу #5CF4 (двухбайтовое слово), хранит в себе номера  тре-
ка и сектора, следующих вслед за последним прочитанным сектором.
По завершении загрузки какого-либо файла в этой ячейке будет на-
ходиться как бы указатель на начало следующего файла. Исходя из
изложенного, легко предположить, что нужно сделать, чтобы загру-
зить следующий файл (или какую-либо  его  часть) - нужно  взять
значение слова из ячейки #5CF4 и поместить его  в пару  DE  как
параметр "трек/сектор" для функции 5:
	LD HL,адрес_загрузки
	LD DE,(#5CF4)
	LD BC,#XX05 ; где XX - количество загружаемых секторов
	CALL #3D13.
Для использования такого приема нужно соблюсти простейшее  усло-
вие - файлы, подлежащие последовательной загрузке, должны  быть
записаны друг за другом без наличия стертых файлов между ними.
А теперь - внимание! С файлами типа  "Бейсик-программа"  TR DOS
оперирует с одной интересной особенностью: при загрузке  Бейсик-
программы на исполнение TR DOS берет из каталога диска длину фа-
йла    в   б а й т а х, не обращая внимания на длину в секторах.
Она сама вычисляет количество секторов, соответствующих  указан-
ной в каталоге длине в байтах, и грузит ровно столько. Если Бей-
сиковый загрузчик имеет длину, скажем, 209 байт, а длина  в сек-
торах указана, к примеру, 68 - по команде "RUN" или  "LOAD"  бу-
дет загружен один-единственный сектор, соответствующий  размеру
файла в 209 байт. Вот отсюда и вытекает замечательная возможнос-
ть объединять вместе в один файл и Бейсиковый загрузчик,  и сле-
дующий за ним блок кодов. Сделать это можно, конечно, и вручную-
сложить длины в секторах загрузчика и последующего  файла  (фай-
лов), занести результат в поле длины файла в секторах бейсик-за-
грузчика и аккуратно удалить из каталога ставшие ненужными  ука-
затели (дескрипторы) на файлы данных. А  потом  скорректировать
данные в 9-м секторе так, чтобы количество файлов стало соответ-
ствовать получившемуся  и  параметры "первый свободный трек/сек-
тор", "количество свободных секторов" несли в себе истинные зна-
чения. Это можно сделать с помощью любого "диск-доктора".  Рабо-
та, конечно, не слишком сложная, но если допустить ошибку,  пер-
вая же новая запись на диск испортит все!  К  счастью,  имеются
инструменты, с помощью которых можно "сливать" файлы одним нажа-
тием на клавишу и без всякого риска. Одним  из наиболее  извест-
ных из них является Advanced Disk Monitor - ADM 7.08. Для  слия-
ния файлов в ADM наведите указатель на начальный файл и нажмите
Symbol Shift + C (connect - соединить). На ваших глазах  нижняя
часть каталога "подтянется" к начальному файлу; следовавший  за
начальным файл исчезнет, а начальный файл пополнеет на величину
объема "исчезнувшего" файла. Операцию можно повторить для подли-
вания еще одного файла, и т.д. Закрепить  произведенные  измене-
ния можно с помощью операции переименования: нажмите N; если на-
до, переименуйте файл; нажмите Enter. Результат запишется  в ка-
талог на диск.
В заключение привожу полный текст загрузчика и стартовой програ-
ммы для демы "DIGITAL TUNE 1" с комментариями:

	DI
	LD HL,50000	; адрес загрузки упакованной картинки
	LD DE,(#5CF4)	; трек/сектор
	LD BC,#0F05	; 15 (#0F) секторов для чтения
	XOR A
	CALL #3D13	; вызов TR DOS
	CALL 50000	; распаковка картинки на экран
	DI
	LD HL,28964	; адрес загрузки основного блока
	LD DE,(#5CF4)	; трек/сектор
	LD BC,#4F05	; 79 (#4F) секторов для чтения
	XOR A
	CALL #3D13
	DI
	LD A,19		; номер страницы
	LD HL,35374	; адрес начала данных для страницы 3
	LD DE,4472	; длина блока кодов
	CALL LDIRDT	; пересылаем в 3-ю страницу
	LD A,20		; так же для 4-й страницы
	LD DE,4812
	CALL LDIRDT
	LD A,22		; так же для 6-й страницы
	LD DE,4494
	CALL LDIRDT
	LD HL,35373	; перемещаем
	LD DE,37641	; на свое место
	LD BC,6410	; блок кодов
	LDDR		; основной памяти
	CALL 31232	; распаковываем основной блок
	LD A,23		; включаем 7-ю страницу (так надо)
	LD BC,32765
	OUT (C),A
	EI
	CALL 31238	; инициализируем музыку
LOOP:	CALL 31232	; проигрываем дему
	JR LOOP
LDIRDT:	LD BC,32765	; подпрограмма распихивания по памяти
	PUSH BC
	OUT (C),A	; включаем страницу
	LD C,E		; переносим из DE в BC, сколько байт...
	LD B,D
	LD DE,#C000	; ...нужно переслать на адрес #C000...
	LDIR		; ...и пересылаем
	PUSH HL
	CALL #C000	; распаковываем
	POP HL		; восстанавливаем HL и BC
	POP BC
	LD A,16		; восстанавливаем основную память
	OUT (C),A
	RET		; возврат.

Вот и все. До встречи!

[ Продолжение темы "Ассемблер" следует ].




Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Презентация - E-Motion, Spazm, SE-Editor, Perfect, Klademiner, Staketris, Italia.
Игры - рецензия на игры Monstrland.
Чернокнижник - Я чернокнижник, я продал свою душу Князю Тьмы!

В этот день...   14 ноября