как простое решение, можно разместить в непереключаемой памяти менеджер, код процедур компилить в окно переключаемой памяти. При компиляции каждый вызов процедуры компилить в чтото вроде такого кода:
Код:
LD HL,procedure_address
CALL MANAGER_CALL
менеджер по табличке будет находить в какой странице находится процедура, переключать страницу и делать вызов процедуры. По возврату управление опять передается в менеджер, он переключает страницу назад и после этого возвращает управление назад в вызвавший процедуру код.
Как альтернативу, можно передавать менеджеру вместе с адресом процедуры также и страницу, где она находится, тогда не нужно будет хранить таблицу страниц, но код вызова увеличится.
Чтобы не портить регистры, можно использовать такой подход:
Код:
CALL MANAGER_CALL
DW procedure_addr
DB procedure_page
Менеджер посмотрит откуда произошел вызов и прочитает адрес процедуры и номер страницы памяти. А при возврате добавит к значению в стеке 3, чтобы управление вернулось на следующую инструкцию. Минус - такой код тяжелее будет отлаживать в отладчике, т.к. DW и DB будут рассматриваться дизассемблером как инструкции.
Тут есть простор для фантазии. Можно адрес процедуры и номер страницы загонять в стек перед вызовом. Правда все это увеличивает размер кода производящего вызов.
С указателями тяжелее, тут нужно искать компромисс между коррекцией страницы памяти при каждой модификции указателя (заметно снизит производительность при поэлементном доступе к массивам) и анализом кода на предмет необходимости переключения страниц для используемого диапазона индексов относительно указателя.