nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 28 Mar 2024 09:28



Reply to topic  [ 23 posts ]  Go to page 1, 2  Next
DLL для Спринтера (LIBMAN) 
Author Message
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
http://nedopc.org/nedopc/sprinter/download/libman.zip (32K)

Code:
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

P.S. Что-то похоже в какой-то момент у меня потерялся вот этот функционал при вызове функции 0:
Quote:
... При вызове этой функции через регистр А ей будет передан идентификатор открытого файла библиотеки для того, чтобы библиотека, при необходимости, могла загрузить из файла дополнительные данные (менеджер загружает столько байт, сколько указано в поле #02)...
Надо будет исправить т.к. наличие библиотек, подгружающих свой хвост, который длиннее отведённых библиотеке 16кб, было бы очень неплохой фичей...

_________________
:dj: https://mastodon.social/@Shaos


13 Dec 2020 00:21
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
В сентябре 20004 года Василий Иванов сделал свой обновлённый вариант LIBMAN v1.3:

http://www.nedopc.org/forum/viewtopic.php?p=68967#p68967

Vasil Ivanov wrote:
Вчера немного поправил твой LIBMAN для DLL-ек. Теперь он нормально работает с библами, у которых таблица перемещений
идет сразу за "своим" кодом (т.е. в начале рел-таблицы не требуется 4 нулевых байта (32 бита, для прохода dll-заголовка)).
Этот формат обозвал как "L1". Его будет (уже выдает) выдавать линкер от SOLID C.
LIBMAN теперь версии 1.3. Надеюсь ты не против? ;)
...
Фактически все изменения LIBMAN-а - это прибавка 32 байт (размер
заголовка) к началу корректируемого кода, для формата L1. Вот и все.
Да еще малька соптимизил код менеджера - сейчас он на 48 байт короче оригинала.
Грузил им твою тестовую библиотечку (упакованную, не упакованную),
созданную mk_dll.exe и эту же библиотеку, скомпиленную моим линкером. Все грузилось без проблем.

http://nedopc.org/nedopc/sprinter/download/libman13.zip (171K)

Причём линковка DLL была уже поддержана линкером его Solid C:
Code:
Создание DLL-библиотек

Для создания динамических библиотек служит опция "t". Обратите внимание,
что эта опция отменяет вставку exe-заголовка.
Отслеживается превышение максимального размера dll-библиотеки в 16 kB.
В этом случае линкер выдает предупреждающее сообщение, но линковка библи-
отеки не прерывается.

Создаваемые dll-библиотеки имеют сигнатуру заголовка "L1". Библиотека этого
формата отличается от формата "L0" только тем, что таблица перемещений начи-
нается сразу за концом "своего" кода.
Заголовок dll-библиотеки создается и прилинковывается автоматически, поэто-
му не надо резервировать для него место при написании ассемблерных текстов.
Более подробную информацию по dll-библиотекам смотрите в документации менед-
жера dll-библиотек.

Пример строки вызова линкера:

     LD /TSymple library:0001 test.rel

где:
       "Symple library"  - Строка внутреннего описания библиотеки.
                           Строка описания может содержать пробелы.
                           Длина описания не должна превышать 16
                           символов, иначе линкер выдаст ошибку.

       "0001"            - Внутренний номер версии библиотеки. Может
                           содержать символы 0..9 и A..F (a..f).

       "test.rel"        - объектный файл, служащий для создания библиотеки.

Можно не указывать один из параметров (или все) опции, но символ ":" разде-
лителя параметров должен стоять всегда. В случае отсутствия описания - в
заголовке библиотеки будет стоять пустая строка. В случае отсутствия номера
версии - в заголовке будет стоять нулевой номер. Примеры вызова опции:

     LD /Tsymple library: test.rel
     LD /tМоя библиотека: test
     LD /T:010B test.rel
     LD /t:7 test
     LD /t: test.rel

Обратите внимание, что строка внутреннего описания библиотеки начинается
сразу же за буквой "t" опции. Например, если написать

     LD /T Example:0001 test.rel

то строка описания в заголовке библиотеки будет иметь вид " Example", т.е.
начинаться с пробела.


В ноябре 2004 Василий выкатил апдейт для Solid C с поддержкой загрузки нового формата DLL:

http://nedopc.org/nedopc/sprinter/download/sc_dll.zip (18K)

Code:
Archive:  sc_dll.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
    21023  2004-11-11 23:22   CLIB.IRL
     1223  2004-11-12 00:59   DLL.C
     1087  2004-11-12 00:40   DLL.RUS
      796  2004-11-26 00:45   DLL.TXT
      814  2004-11-12 00:53   STDLIB.H
---------                     -------
    24943                     5 files

Подробнее про сишный вызов DLL было в форуме тут:

http://www.nedopc.org/forum/viewtopic.php?p=70452#p70452

_________________
:dj: https://mastodon.social/@Shaos


13 Dec 2020 00:25
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Вызов функции DLL может быть и выглядит несколько длинноватым (см. ниже), однако например если мы хотим поработать с плавающей точкой или сделать заливку полигона или GIF скажем подекодить на экран, вызвав соответствующую функцию уже загруженной DLL либы, то время вызова этой функции DLL будет пренебрежимо мало по сравнению со временем выполнения этой самой функции DLL (это 490 тактов до передачи управления в функцию и ещё 154 такта после - т.е. всего 644 такта оверхеда, что есть 92 мкс при 7 МГц процыке):
Code:
; <><><><><><><><><><><><><><><><><>
; user data in a,de,ix,iy
;       ld      hl,(handle)
;       ld      b,function
;       call    l_call
;       jp      c,error

_L_CALL:
        push    hl
        push    de
        push    bc
        push    af
   xor   a
   ld   (lcflag),a
   ld   a,b
   ld   (lc_fun),a
        ld      a,l
        rla
        rla
        ld      d,0
        ld      e,a
        ld      hl,LIBR
        add     hl,de
        ld      a,(hl)
        or      a
        jp      z,lc_er2
        inc     hl
        ld      a,(hl)
        push    af
        inc     hl
        ld      h,(hl)
        ld      l,#20
        ld      (lcstart),hl
        ld      a,h
        and     #C0
        ld      (lcoldp),a
        cp      #40
        jr      nz,lc1
        in      a,(#A2)
        jr      lc3
lc1:    cp      #80
        jr      nz,lc2
        in      a,(#C2)
        jr      lc3
lc2:    cp      #C0
        jr      nz,lc_er3
        in      a,(#E2)
lc3:    ld      (lcoldw),a
        pop     af
   push   de
        ld      bc,#0038        ; SETWIN
        rst     10h
   pop   de
        pop     af
        pop     bc
        ld      hl,(lcstart)
        ld      d,0
        ld      e,b
        add     hl,de
        add     hl,de
        add     hl,de
        pop     de
        ld      bc,lc_
        push    bc
        jp      (hl)            ; CALL FUNC <<<<<<<<<<<<<<<<<<<<<<<<<<<<
lc_:    pop     hl      ; restore handle
   ld   c,a      ; save A to C
   jr   nc,lc4_
   ld   a,(lc_fun)
   or   a      ; test for FUN0
   jr   nz,lc4_   
   ld   a,#FF
   ld   (lcflag),a
lc4_:   ld      a,(lcoldw)
        ld      b,a
        ld      a,(lcoldp)
        cp      #40
        jr      nz,lc1_
        ld      a,b
        out     (#A2),a
        jr      lc3_
lc1_:   cp      #80
        jr      nz,lc2_
        ld      a,b
        out     (#C2),a
        jr      lc3_
lc2_:   cp      #C0
        jr      nz,lc_er0
        ld      a,b
        out     (#E2),a
lc3_:   ld   a,(lcflag)
   rlca         ; set c-flag
   ld   a,c      ; restore A
        ret
lc_er3: pop     af
lc_er2: pop     af
        pop     bc
        pop     de
lc_er1: pop     hl
lc_er0: scf
        ret

Однако если у нас будут либы поменьше с более лёгкими функциями (типа 32-битная арифметика), то можно придумать способ работы с ними, который был бы чуток побыстрее. Например, вместо
Code:
        ld      hl,(handle)
        ld      b,function
        call    l_call
        jp      c,error
можно вызвать другую функцию (которую ещё надо написать) скажем l_freeze:
Code:
        ld      hl,(handle)
        ld      b,function ; ???
        call    l_freeze
        jp      c,error
        ld      (frozen),de
которая будет оставлять окно с либой подключенным, а в регистровой паре DE вернёт указатель на ряд JMP-ов, который пользователь может использовать далее для непосредственного вызова пользовательских функций библиотеки используя формулу frozen+N*3 для вызова функции N, причём функции 0 и 1 не должны вызываться таким способом т.к. это функции INIT и FINIT, вызываемые только самим менеджером. После того как непосредственная работа с библиотекой закончена, программа может разморозить либу с помощью функции l_unfreeze (которой также пока нету):
Code:
        ld      hl,(handle)
        call    l_unfreeze
        jp      c,error
После этого либа остаётся загруженной, но спрятанной, и как и раньше будет доступна через вызов l_call. Если программа до вызова l_unfreeze вызвала l_freeze для другой либы, то l_unfreeze для предыдущей либы выполняется автоматически.

P.S. Чтобы исключить возможность ошибочного вызова пользователем функций 0 или 1 можно frozen сразу "отмотать" на запрошенную функцию, передав скажем в регистре B номер первой желаемой функции, например 2 (первая пользовательская функция), тогда DE будет сразу указывать на JMP FUNCTION2, хотя это всё может ещё более запутать программиста...

P.P.S. Также в будущем можно поддержать "умные" либы, которые не надо грузить каждый раз когда вызывается l_load - скажем если первым символом в названии такой либы будет $, то если она уже была загружена в нужное окно, то грузить её снова ненадо - просто выдаём обратно тот же идентификатор либы (возможно с инкрементом старшей части хэндлера чтобы отличить инстансы друг от друга), но для работы с данными, уникальными для каждой программы-пользователя, у таких либ должен быть иной механизм, например через функцию 2 каждая программа будет давать ей указатель на буфер, с которым надо работать и либа будет этот буфер запоминать для данного пользователя. Такой функционал потребуется тогда, когда LIBMAN переедет в DSS либо будет висеть резидентом и откликаться на RST #20 (тогда и регистр C пригодится) - в этом случае максимальное количество одновременно подгруженных DLL-ей можно увеличить с 64 до 256, что потребует буфера для хранения информации о библиотеках в 1024 байта.

_________________
:dj: https://mastodon.social/@Shaos


13 Dec 2020 02:21
Profile WWW
Maniac

Joined: 05 Oct 2009 19:44
Posts: 223
Location: 212.164.105.5
Reply with quote
Quote:
_L_CALL:

первую половину функции нужно явно переделать. таблицу переделать в 512 байт (младший, старший байты адреса) с процедурой декодирования аля dss.
+ к этому размещение только в 0м окне, без необходимости вычислять окно.
всё это ускорит вызов раза в 2.
сейчас RST #20 и RST#28 свободны (вплоть до адреса 0x002f). 16 байт для размещения "переключалки" 0го окна туда и сюда более чем должно хватить. можно уже сейчас эксперементировать и тестировать функционал библиотек в текущей версии доса. например, программа libman.exe установит диспетчер на рст 0х20, запросит у доса страничку для размещения своего функционала и страничку для размещения либ.
solid c я не пользуюсь, оно не интересно. нет ansi и нет 32 бита.

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


13 Dec 2020 21:51
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
не - таблица SIZE/8 перемещает только с шагом 256 байт (учитывается только старший байт всех адресов) - насколько я помню MSX-DOS себя так перемещал в верхнюю память - это общепринятый метод
или ты про какую таблицу? таблица релокации используется только при загрузке
если речь идёт про вызовы функций, то их обычно несколько - зачем отводить под них 512 байт если в либе скажем только 3 точки входа?
окно 0 не подходит т.к. для прерывания должен стоять хук и обработчик для биоса, потом либа сама может вызывать функции DSS - поэтому 0 окно у меня используется только для первичной загрузки
естественно поддерживается несколько либ - в этой версии либмана до 64 либ одновременно
а Solid C таки можно считать стандартом де факто - других сей на Спринтере нету :)

_________________
:dj: https://mastodon.social/@Shaos


13 Dec 2020 23:06
Profile WWW
Maniac

Joined: 05 Oct 2009 19:44
Posts: 223
Location: 212.164.105.5
Reply with quote
Quote:
Solid C таки можно считать стандартом де факто - других сей на Спринтере нету

ну тогда на Спринтере нету сей. солидом мало что можно сделать. за всё время так никто ничего не не сделал.
Quote:
окно 0 не подходит т.к. для прерывания должен стоять хук

прерывания на момент переключения можно запретить со стороны либмана, на случай стоковых прерываний первой же командаой DI либо, на +1 байт смещение, если пользователь имеет свой обработчик и прерывания запрещать не требуется.
да и с 0й страницей по части вызова доса тоже можно придумать вариант. раскидывать либы по окнам в условиях, когда и так окошек мало, как бы расточительно. может случится так что все 4 окна уйдут под либы.
опять таки, ты заставляешь "юзера" шарить, какая либа в каком окне, изворачиваться. а если все либы в 0м окне, т.е. в одном месте, это сильно снизит требования по входу для юзера.


14 Dec 2020 01:53
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
либа в окно подключается только тогда, когда её используют т.е. варианта когда во всех окнах либы - не будет
и юзер не будет "шарить" по окнам - он сам желаемое окно задал, когда либу грузил - соответственно он должен понимать, что делает

P.S. LIBMAN 1.2 был четвёртой итерацией менеджера (версия от Василия - уже пятая итерация) и на каждой итерации функционал обсуждался на форуме петерсов и с самими петерсами (например возможность подключения либы в любое окно кроме нулевого специально запрашивалась, насколько я помню) - никаких лишних усложнений небыло - всё обговорено и обсуждено так что я буду цеплять то что есть на RST #20 и никаких фундаментальных переделок делать небуду - все старые либы должны работать как есть...

_________________
:dj: https://mastodon.social/@Shaos


14 Dec 2020 02:59
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Sayman wrote:
Quote:
Solid C таки можно считать стандартом де факто - других сей на Спринтере нету

ну тогда на Спринтере нету сей. солидом мало что можно сделать. за всё время так никто ничего не не сделал.

Это твое личное мнение - каждый имеет право на своё лично мнение и моё личное мнение отличается от твоего :roll:

_________________
:dj: https://mastodon.social/@Shaos


14 Dec 2020 03:12
Profile WWW
Maniac

Joined: 05 Oct 2009 19:44
Posts: 223
Location: 212.164.105.5
Reply with quote
Мнение, то мнение, только вот попробуй написать на этом солиде что-то толковое. можно взять и попробовать мой старый фдиск на нём собрать. или попробовать написать что-то графическое. гляделку бмп файлов (ну просто так, чтобы проверить). сразу упрёшься в ограничения этого компилятора. т.е. практического применения не видно для него. даже банально парсер ini файлов мой древний тут не взлетит. переделать может и можно, но проще уже под асм переложить будет.
если так хочется нативный си компилятор, то можно как то декомпилить хайтех си и адаптировать под спринтер. или взять исходники BDS C и допилить до уровня ANSI.


14 Dec 2020 03:40
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
ну адаптируй если очень хочется :)

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

_________________
:dj: https://mastodon.social/@Shaos


14 Dec 2020 03:58
Profile WWW
Maniac

Joined: 05 Oct 2009 19:44
Posts: 223
Location: 212.164.105.5
Reply with quote
в общем проехали тему сей. про либмана.
законным способом, ничего не ломая прямо сейчас, в рамках 1.62.хх можно доработать system.exe, чтобы функция либмана заехала в него. тогда, при запуске шелла, будет инициализирована точка входа рст20, будет корректно работать всё остальное и либы в том числе. при этом странички занятые либами освобождаться не будут т.к.. первичный шел не закрываем. при попытке закрыться он будет перезапускать себя по новой. таким образом даже если юзер по ошибке сделает exit в первичном шелле и вся его память, включая либы будет освобождена, то он сам всё перезапросит и переставит. законного, в рамках 1.62 способа не существует. остальные варианты обсужденные в группе - костыльные.

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


15 Dec 2020 00:58
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
согласен

вопрос какой system.exe взять за основу? по идее в официальном есть комментарии и вменяемые названия для меток

с другой стороны в версии Василия добавлена достаточно продвинутая история и исходник порезан на тематические подсистемы

может как-то можно совместить это всё и сделать единый суперисходник?...

_________________
:dj: https://mastodon.social/@Shaos


15 Dec 2020 01:19
Profile WWW
Maniac

Joined: 05 Oct 2009 19:44
Posts: 223
Location: 212.164.105.5
Reply with quote
можно, разрешаю :mrgreen:


15 Dec 2020 01:47
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Sayman wrote:
можно, разрешаю :mrgreen:

ну я тогда по ходу пьесы воткну туда copy и move (пока тупой с копированием и удалением) и сделаю алиасы ls, cp и mv :lol:

прогресс будет в топике про шелл с памятью: http://www.nedopc.org/forum/viewtopic.php?f=60&t=8473

(но всё что касается либмана будет тут)

_________________
:dj: https://mastodon.social/@Shaos


15 Dec 2020 02:42
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Итак, шелл стартует как приложение, работающее в странице 2 (#8000...#BF00), однако при работе с либами там может находиться программа пользователя их вызывающая или сама вызываемая либа т.к. она может запускаться в одном из трёх окон 1,2,3 (нулевое окно отпадает, т.к. либы могут пользоваться точками входа DSS и BIOS, а также предполагать, что у нас работают прерывания). Пользователь при загрузке либы сам устанавливает в каком окне он её ожидает видеть, соответственно там не должно быть его стека и данных, на которые могут указывать аргументы, однако сама точка вызова RST #20 в программе пользователя может находиться в том же окне, куда потом откроется либа, потому что скорее всего либман будет пускаться из нулевого окна (временно запретив прерывания и перещёлкнув нулевое окно с DSS на страницу шелла и вернув всё обратно после отработки функции) и возврат также будет делаться через нулевое окно через код прихаканный в DSS. Однако, загружающий код в функции либмана L_LOAD активно использует функции DSS - это значит, что в нулевое окно этот код вставлять нельзя и у либмана должна быть ещё ретранслируемая часть, которая будет оттранслирована для всех трёх окон 1,2,3 и включена в нужное окно при загрузке и выгрузке очередной либы (например как часть буфера). Вызовы L_CALL, L_INFO и L_FREE можно полностью реализовать только через вызов функций биоса (повторив реализацию DSS-ных SETWIN[n] и FREEMEM в коде шелла), соответственно их можно вызывать в нулевом окне убрав DSS в тень.

_________________
:dj: https://mastodon.social/@Shaos


15 Dec 2020 23:50
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 23 posts ]  Go to page 1, 2  Next

Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.