Радио-86РК/Радио 03-88/Перемещающий загрузчик
Данный материал защищён авторскими правами!
Использование материала заявлено как добросовестное, исключительно для образовательных некоммерческих целей. Автор: Д. ЛУКЬЯНОВ |
Опубликованный в прошлом номере РЕДАКТОР ПАМЯТИ обладает свойством загрузки в самые старшие адреса доступной пользователю памяти. Операцию перемещения и соответствующей коррекции кодов программы осуществляет модуль ПЕРЕМЕЩАЮЩЕГО ЗАГРУЗЧИКА (табл.1), представляющий и самостоятельный интерес.
Таблица 1.
; ******************************************************** ; * ПЕРЕМЕЩАЮЩИМ ЗАГРУЗЧИК ОБЪЕКТНЫХ ПРОГРАММНЫХ МОДУЛЕИ * ; * для радиолюбительского компьютера "Радио-86РК" * ; ******************************************************** ; Внимание; Эта программа должна загружаться с адреса 0000Н ; и использовать заранее созданную ВIТМАР-таблицу ; Вызовы резидентного монитора Радио-86РК F830 GETMEM: EQU 0F830Н ; Вернуть значение МАХRАМ в (HL) F8ЗЗ PUTMEM: EQU 0F833Н ; Заменить MAXRAM на содержимое (HL) F81B MSB: EQU 0F81BH ; Напечатать сообщение, указанное (HL) F815 PRINTA: EQU 0F815Н : Напечатать содержимое (А) в HEX F836 WSTART: EQU 0F836Н ; Вход в CLI монитора. 0000 ORG 0 0000 C31200 INIT: JMP START ; Основной "ход в загрузчик с авто- 0001 GO$ADR: EQU INIT+I ; установкой aдреса по МАХRАМ. 0003 С32900 INIT1: JMP STARTI ; Вход без автоустановки адреса 0006 00 TOPS: DB 0 ; Младший байт длины программы TASK ВВ07 00 BLOCKS: DB 0 ; Старший байт длины программы TASK ; TOPS&BLOCKS вместе содержат 16- ; битное представление верхней грани- ; цы прикладной программы. 0008 00 ASTART: DB 0 ; Адрес начала области перемещения 0009 00 SHIFT: DB 0 ; (16-битное число) 000A 0000 LENGTH: DW 0 ; длина TASK в байтах 000C 0000 FILE: DW 0 ; Адрес начала TASK в ОЗУ РК. 000E 0000 BITMAP: DW 0 ; Адрес начала таблицы BITMAP 0010 0000 CONTROL:DW 0 ; Адрес старта TASK. ; Загрузка с автоматическим резервированием памяти. 0012 CD30F6 START: CALL GЕТМЕМ ; Запросить границу ОЗУ у Монитора 0015 ЗА0600 LDA TOPS ; Сравнить, уместится ли "хвост" 0018 BD СМР L ; копии при перемещении на целое 0019 F21D00 JP 10$ ; число 256~байтнмх блоков. 001С 25 DCR Н ; Нет " зарезервировать на блок больше ' 001D 3A0700 10$: LDA BLOCKS ; Получить адрес начала области 0020 2F CMA ; перемещения по размеру TASK. 0021 ЗС INR А 0022 84 ADD Н 0023 67 MOV Н,А 0024 2E00 MVI L,0 0026 220800 SHLD ASTART ; Сохранить полученное значение ; для единообразия. ; Загрузка с ручным резервированием памяти. 0029 2A0800 START1: LHLD ASTART ; 002C Е5 PUSH H ; Start ADDRES is on stack BB2D EB XCHG 0B2E 2A0A00 LHLD LENGTH ; Взять размер TASK в (ВС) 0031 44 MOV В,Н 0032 4D MOV C,L 0033 2A0C00 LHLD PILE ; Параметры подготовлены; 0036 ЕB ХСНО ; (ВС) "длина, <DE) "начало TASK, 0037 С5 PUSH В ; (HL) "начало области копии. ; Пересылка прикладной программы в "верхние" адреса 0038 78 LOOP: МОV A,В 0039 В1 ОRA С 003A СА4500 JZ ENDLOOP 003D 1A LDAX D 003Е 77 MOV М,А 003F 13 INX D 0040 23 INX Н 0041 0В DCX В 0042 СЗЗ800 JMP LOOP ; Коррекция адресов в копии программы TASK 0045 ENOLOOP: 0045 С1 POP В : Длина B04b D1 POP D ; Начальный адрес 0047 D5 PUSH D 0048 2A0E00 LHLD BITMAP ; Взять указатель на таблицу 004В E5 PUSH Н ; коррекции 004С 62 MOV H,D 004D 78 10$: MOV А,В ; Начать коррекцию по таблице 004Е B1 ORA С ; Все байты скорректированы? 004F СА6B00 JZ REPORT ; Да, выход из программы 0052 0В DCX В ; Нет, Продолжаем проверку 0053 7В MOV А,Е 0054 Е607 ANI 7 ; Нужен новый байт на BITMAP? 0056 С25Е00 JNZ 20$ ; Нет, анализируем текущие биты 0359 ЕЗ XTHL ; Да, загрузим новый байт с L 005A 7E MOV А,М 005B 23 INX Н 005C Е5 XTHL 005D 6F MOV L,A 005Е 7D 20$: MOV A,L ; Обработка текущего байта BITMAP: 005F 17 RAL ; начиная со старшего разряда 0060 6F MOV L,A ; (На необходимость коррекции 0061 D26700 JNC 30$ ; указывает старший бит. т.е. <f:Y> 0064 1A LDAX D 0065 84 ADD Н 0066 12 STAX D 0067 15 30$: INX D 0068 С34D00 JMP 10$ ; Выход из загрузчика с печатью сообщения и изменением ; значения верхней границы ОЗУ MAXRAM в Мониторе. 006В Е1 REPORT: POP Н 006C 218F00 LXI H,STMSG ; Отпечатать новое значение 006F CD18F8 CALL MSG ; стартового адреса копии TASK 0072 E1 POP Н ; 0073 CD33F8 CALL PUTMEM ; Изменить NAXRAM для "захлопывания" 0076 ЕВ XCHG ; загруженной копии е ОЗУ. 0077 2А1000 LHLD CONTROL ; Изменить адрес перехода по "Б0" 007А 29 DAD Н ; на стартовый адрес копии TASK 007В 220100 SHLD GO$ADR 007Е 7С MOV A,H 007F CD15F8 CALL PRINTA 0082 7D MOV A,L 008З CD15F8 CALL PRINTA 0086 21А400 LXI H,CRLF ; Подготовить HOByte строку для CLI 0089 CD18F8 CALL MSG 008C C336F8 JMP WStart NOGEN 008F 204E45 STMSG: DB NEW START ADDRESS! ,0 00A4 0D0A00 CRLF: DB 0DH,0AH,0
Использование перемещающего режима загрузки предпочтительно для большинства разрабатываемых программ, поэтому мы и приводим исходный текст этого важного программного модуля ПОЛНОСТЬЮ.
Как видно из текста программы, при запуске с адреса 0000Н загрузчик получает у МОНИТОРА адрес верхней границы доступного ОЗУ и вычисляет смещение, которое необходимо задать от начала ОЗУ до области загружаемой программы, чтобы она смогла полностью разместиться в ОЗУ. После этого следует процедура коррекции байтов, которые в кодах программы содержат старшие части изменившихся переходов и меток внутри программы. Поскольку для такой коррекции необходима дополнительная информация о том, как необходимо трактовать байты программы, программа пользуется побитной таблицей коррекции BITMAP, полученной вместе с машинными кодами при трансляции загружаемой программы с помощью МАКРОАССЕМБЛЕРА.
Каждый байт этой таблицы описывает 8 последовательных байт машинного кода. Установленный в «1» бит этой таблицы помечает байт, который необходимо корректировать. Старший бит байта таблицы описывает самый первый байт кодов программы, а остальные — следующие по порядку 7 бит. Такую таблицу для небольших программ можно создать и вручную, пользуясь листингом трансляции. Эта же таблица поможет однозначно дизассемблировать программы, имеющиеся только в машинном коде.
Информация, содержащаяся в таблице BITMAP, является исчерпывающей для перемещения программ с дискретностью 256 байт и позволяет, в частности, настроить программу в кодах на конкретные адреса или переместить ее так, чтобы она была настроена на работу в одной области адресного пространства, а переместилась в другую. Это необходимо, например, для записи программ в ПЗУ. Областью перемещения тогда будет область буфера программатора, а настройка должна быть произведена на область, где будет расположено запрограммированное ПЗУ. Для такого режима перемещающий загрузчик имеет вторую точку входа (0003Н), причем перед запуском программы необходимо соответствующим образом скорректировать содержимое блока параметров загрузчика (ячейки 0006H — 0011Н).
Программа, подлежащая перемещению, должна быть оттранслирована с адреса 0000Н, а адрес массива памяти, где будут размещаться ее коды до загрузки, указывается в ячейках 000СН, 000DH области параметров загрузчика.
Квалифицированные радиолюбители могут дополнить функциональные возможности экранного РЕДАКТОРА ПАМЯТИ. Для этого в наиболее важных точках программы зарезервировано по 3 байта (заполнены командой NOP) для размещения команд перехода на внешние программы и подпрограммы. В табл.2 приведено расположение этих точек и условия, при которых происходит выход на них. Следует также учесть, для удобной мнемоники команд в РЕДАКТОРЕ введен режим префикса: сначала нажимают клавишу АР2, а затем одну из алфавитно-цифровых клавиш.
Таблица 2
ЗАРЕЗЕРВИРОВАННЫЕ АДРЕСА ДЛЯ РАСШИРЕНИЯ ФУНКЦИИ РЕДАКТОРА
Адрес | Имя | функция | Условия выхода и передаваемые параметры |
---|---|---|---|
0023 | EXT1 | Основное меню | Ни одна из перечисленных в меню директив не выбрана. (a)=ascii код введенной клавиши |
0466 | ЕХТ2 | DUMP-редактор | Ни одна из возможных директив редактора не совпадает с введенной. (А)=код клавиши |
0549 | EXT5 | Тo же, peжим Letter | Введена не команда управления курсором, (А)=АSСII -код введенного символа. |
0642 | ЕХТ3 | Программатор РПЗУ | Введен тип РПЗУ, не поддерживаемый этой версией. (А)=код типа РПЗУ (в HEX- записи) |
07C7 | ЕХТ4 | Программатор ППЗУ | Введен тип ППЗУ, не поддерживаемый этой версией. (А)=код типа ППЗУ (в НЕХ- записи) |
0891 | ЕХТ7 | DUMP-редактор | В [Hex] или [Letter] режимах редактора набрана <ESC>-последовательность, не отрабатываемая этой версией. (А)=код второго символа в набранной последовательности |
08B0 | ЕХТ9 | Despatch | В слове по этому адресу необходимо разместить адрес входа в дизассемблер. Возврат из этой подпрограммы должен быть по RET |
08B3 | EXT8 | Despatch | Первый байт должен содержать символ, следующий за <ESC>, а следующее за ним слово — адрес подпрограммы, отрабатывающей эту <ESC>-последовательность |
097В | EXT10 | Основное меню | Первый байт должен содержать символ меню, а следующее слово — адрес перехода по этому символу на подпрограмму пользователя (например: ED*MICRON* или Бейсик). |
Примечание:
- <ESC>/A = Курсор вверх,
- <ESC>/B = Курсор вниз,
- <ESC>/C = Курсор вправо,
- <ESC>/D = Курсор влево,
- <ESC>/<ESC> = выход в монитор РК,
- <ESC>/L = Выход в подключаемый дополнительно дизассемблер
Д. ЛУКЬЯНОВ, г. Москва
От редакции. Исходный текст перемещающего загрузчика был подготовлен на другом компьютере. Чтобы воспользоваться им для «Радио-86РК», необходимо операторы SET заменить операторами EQU, а после их имен поставить двоеточие.