| nedoPC project | nedoPC group | nedoPC forums |

LIBMAN


  • LIBMAN.ZIP (32K) - исходники менеджера библиотек для Спринтера
  • LIBSHAOS.ZIP (10K) - набор тестовых библиотек

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)

Благодарности (в алфавитном порядке):
 AcidRain/PowerAmiga^mOOds
 Anton Enin
 Garry Lancaster
 PetersPlus Ltd.
 Stels/Myth corp.
 Vasil Ivanov
 


Rambler's Top100
^ Вверх
©2002-2010 nedoPC.org