Радио-86РК/Радио 03-88/Перемещающий загрузчик

Материал из Emuverse
Данный материал защищён авторскими правами!

Использование материала заявлено как добросовестное, исключительно для образовательных некоммерческих целей.

Автор: Д. ЛУКЬЯНОВ

Источник: http://retro.h1.ru/RK86/Loader/MoveLoad.html

Опубликованный в прошлом номере РЕДАКТОР ПАМЯТИ обладает свойством загрузки в самые старшие адреса доступной пользователю памяти. Операцию перемещения и соответствующей коррекции кодов программы осуществляет модуль ПЕРЕМЕЩАЮЩЕГО ЗАГРУЗЧИКА (табл.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, а после их имен поставить двоеточие.