/* * bank1.c — __banked модуль (страница W3 подменяется трамплином на время * вызова). Задача: проверить, что ИЗ БАНКА можно рисовать примитивами * libbgi и звать функции W1/W2, и что после этого банк ЖИВ (его страница * вернулась в W3). * * Резидент (res_draw) отсюда НЕ зовём сознательно: пока исполняется банк, * резидентной страницы в адресном пространстве нет (правило R2). */ #include #include extern uint8_t home_helper(uint8_t x); /* функция в W1/W2 (рисует сама) */ /* ВАЖНО: писучие статики __banked-модуля линкуются В СТРАНИЦУ БАНКА * (адрес 0x1C000+), поэтому снаружи их не прочитать — из W1/W2 по 0xC000 * видна РЕЗИДЕНТНАЯ страница. Состояние банка держим в главном модуле. */ extern uint8_t bank_page_before, bank_page_after, bank_page_after_home; extern uint8_t bank_alive; /* Текущая страница W3 (порт 0xE2). ОТДЕЛЬНОЙ __naked-функцией: инлайновый * `in a,(0xE2)` посреди тела затирает A, куда SDCC уже положил параметр — * в первой версии пробника из-за этого цвет заливки становился номером * страницы (0xF3 = чёрный), и «резидент не рисовал». */ static uint8_t w3_page(void) __naked { __asm__("in a, (#0xE2)\n\tret"); } uint8_t bank_run(uint8_t arg) __banked { uint8_t r; bank_page_before = w3_page(); /* 1) прямое рисование примитивом libbgi (он живёт в W1/W2 и сам * открывает/закрывает W3-скобку) */ setfillstyle(SOLID_FILL, CYAN); bar(70, 40, 120, 52); bank_page_after = w3_page(); /* 2) вызов функции W1/W2, которая тоже рисует */ r = home_helper(arg); bank_page_after_home = w3_page(); /* 3) банк ещё исполняется — значит его страница на месте */ bank_alive = 1; return (uint8_t)(r + 1); }