Code: Select all
LIBMAN - Менеджер библиотек для компьютера Sprinter
===================================================
Version 1.2 (August 1, 2002)
Модуль LIBMAN.A предназначен для использования динамически
подгружаемых библиотек (DLL) формата L0 в пользовательских
программах для компьютера Sprinter. При компиляции модуль
занимает около 1К памяти и позволяет загружать, запускать и
выгружать библиотеки. Единственное требование при компиляции -
расположение кода модуля LIBMAN в области #4000-#BFFF.
Формат библиотеки L0:
#00:(2) "L0"
#02:(2) размер загружаемой части библиотеки
#04:(2) смещение до таблицы (размер кода)
#06:(2) размер таблицы
#08:(2) контрольная сумма
#0A:(1) день \
#0B:(1) месяц } - дата создания библиотеки
#0C:(2) год /
#0E:(2) версия библиотеки (1.0 = #0100)
#10:(16) имя библиотеки (заканчивается нулем)
#20: jp init ; подпрограмма инициализации
#23: jp fini ; подпрограмма деинициализации
#26: jp ...
...
перемещающая таблица
...
Со смещения #10 код библиотеки является скомпрессированным.
После 32-байтового заголовка идет таблица переходов на функции
библиотеки. Количество функций никак не ограничивается. Нумеруются
функции с 0. Первые две функции имеют особое назначение - функция 0
для инициализации (вызывается при загрузке) и функция 1 для
деинициализации (вызывается при закрытии) - и не предназначены
для явного вызова из пользовательской задачи. Кроме того функция
0 должна устанавливать регистр A в 0 и обнулять флаг C (проще всего
это сделать с помощью команды XOR A). При вызове этой функции через
регистр А ей будет передан идентификатор открытого файла библиотеки
для того, чтобы библиотека, при необходимости, могла загрузить
из файла дополнительные данные (менеджер загружает столько байт,
сколько указано в поле #02). В случае неудачи, функция 0 должна
взвести флаг C и указать в регистре A код ошибки - в этом случае
менеджер выгрузит библиотеку и вернет код ошибки.
Количество одновременно загруженных библиотек в этой версии - 64.
Библиотеки подгружаются по имени файла с помощью подпрограммы L_LOAD.
Перед вызовом требуется в регистровой паре HL установить адрес
имени файла библиотеки, а в регистре A - требуемую страницу
памяти:
ld hl,filename
ld a,wind ; 1,2,3
call l_load
jp c,error
ld (handle),hl
...
handle dw 0
Здесь, filename - адрес имени файла, заканчивающегося нулем;
wind - номер окна, в котором желательно исполнять подгруженный
код (для 1: #4000-#7FFF, для 2: #8000-#BFFF, для 3: #C000-#FFFF);
handle - двухбайтовая переменная для хранения идентификатора
библиотеки для дальнейшего использования; в случае ошибки функция
возвращает флаг переноса. При загрузке код библиотек переносится
в памяти так, чтобы расположиться максимально компактно. После
успешной загрузки и привязки кода библиотеки к конкретным адресам,
производится запуск функции 0 библиотеки. Размер одной библиотеки
не может превышать 16К.
Информацию о загруженной библиотеке (32 байта заголовка) можно
получить с помощью подпрограммы L_INFO. Идентификатор передается через
регистровую пару HL. Адрес 32-байтного буфера - через регистровую
пару DE:
ld hl,(handle)
ld de,buffer32
call l_info
jp c,error
Если ошибки не произошло, то в буфере будет располагаться
32-байтовый заголовок библиотеки (см.выше) из которого можно
получить информацию о версии спецификации, размере файла
библиотеки, размере кода, дате создания, версии библиотеки и
полном имени библиотеки.
Вызов функций библиотеки производится с помощью подпрограммы L_CALL.
Эта подпрограмма самостоятельно подключает необходимый код в нужное
окно (программист должен корректно указать его при загрузке
библиотеки, чтобы не закрыть открываемой страницей кода
менеджера, данных, стека), передает управление на код
соответствующей функции библиотеки, а затем возвращает обратно ту
страницу, которая была там до вызова функции библиотеки.
Перед вызовом в HL устанавливается идентификатор библиотеки, а в
регистре B - функция библиотеки, которую нужно вызвать. Регистр C
- зарезервирован на будущее:
ld hl,(handle)
ld b,function
call l_call
jp c,error
Об ошибке свидетельствует взведеный флаг переноса. Данные можно
передавать и получать в регистрах A,DE,IX,IY, а также через
второй набор регистров.
Для закрытия библиотеки и особождения захваченной памяти
используется подпрограмма L_FREE, которой нужно передать
идентификатор библиотеки:
ld hl,(handle)
call l_free
jp c,error
Ошибка возвращается во флаге переноса. Перед освобождением
памяти, подпрограмма производит запуск функции 1 выгружаемой
библиотеки.
Для идентификации загруженной библиотеки используется
двухбайтовое число специально для будущих реализаций (возможность
использования одной и той же библиотеки разными процессами,
которым будут выданы разные идентификаторы этой библиотеки).
Для создания библиотек можно использовать программу MK_DLL.CPP
(MK_DLL.EXE откомпилирован для консоли Windows). Пример простой
библиотеки есть в LIB.A. А в TEST.A можно посмотреть как
эта библиотека используется. Файлы TEST.EXE и TEST.DLL являются
бинарными файлами для компьютера Sprinter и соответствуют
исходным текстам TEST.A и LIB.A. Менеджер библиотек LIBMAN.A
подключен внутри исходника TEST.A. Пакетный файл ZM.BAT производит
сборку тестового примера на персональном компьютере под
управлением Windows и при наличии кросс-ассемблера ZMAC.
Copyright (c) 2002, Александр Шабаршин (shaos@mail.ru)
http://shaos.ru/nedopc/sprinter/
Благодарности (в алфавитном порядке):
AcidRain/PowerAmiga^mOOds
Anton Enin
Garry Lancaster
PetersPlus Ltd.
Stels/Myth corp.
Vasil Ivanov
Надо будет исправить т.к. наличие библиотек, подгружающих свой хвост, который длиннее отведённых библиотеке 16кб, было бы очень неплохой фичей...... При вызове этой функции через регистр А ей будет передан идентификатор открытого файла библиотеки для того, чтобы библиотека, при необходимости, могла загрузить из файла дополнительные данные (менеджер загружает столько байт, сколько указано в поле #02)...