ТЕХНИЧЕСКОЕ ОПИСАНИЕ КОНТРОЛЛЕРОВ "АЛЬТПРО"
с доп. памятью 64-512 Кб и версией ПЗУ не ниже 2.00

Фирмой "АльтПро" (экс-"Альтек") выпускаются контроллеры с дополнительной памятью 64, 128, 256, 512 Кб с одинаковой организацией. Все перечисленные контроллеры имеют 8 режимов работы доп. ОЗУ, различающихся, главным образом, адресами подключения дополнительной памяти с выработкой соответствующих сигналов отключения основных ПЗУ/ОЗУ, а также наличием или отсутствием доступа к HALT-режиму процессора БК. Поскольку распределение основной памяти в разных моделях БК существенно различается, часть режимов предназначена для использования с БК0010(-01), часть - с БК11М. Причём тип машины автоматически распознаётся при включении питания, и сразу подключается необходимый для работы режим.

Работа с дополнительной памятью осуществляется через программные запросы к специальному диспетчеру, получившему название "BIOS" по аналогии с IBM. Все точки входа BIOS расположены в области ПЗУ выше 167000 (эта часть получила название ROM-BIOS, она меняться не будет), обработка же запросов производится в загружаемой в ОЗУ части, называемой RAM-BIOS. Прямые обращения к этой части (кроме проверки наличия и считывания номера версии) не практикуются. Если RAM-BIOS в ОЗУ отсутствует, то большинство запросов будет вызывать сигнал ошибки - характерное затухающее подёргивание экрана с прерывистым звуковым сигналом.

BIOS обеспечивает бесконфликтное выделение памяти по запросу, освобождение памяти (обратная операция), пересылку либо обмен массивов, чтение/запись 1 слова, вызов подпрограммы из доп. памяти или безусловную передачу управления (JMP), изменение режима и др.

Корректное использование запросов BIOS обеспечивает взаимную совместимость программного обеспечения, переносимость программ на разные модели БК и контроллеров. Кроме того, использование запросов значительно упрощает и сокращает программы. (Короче, кто не использует запросы - тот сам виноват, такие программы распространять не будем и другим не советуем).

УРОВНИ ЗАПРОСОВ BIOS

В распоряжении программистов имеется 3 уровня запросов BIOS: высокий, средний и низкий. Выделение памяти может быть произведено только на высоком уровне (выделенный фрагмент называется модулем), информация о модулях и свободной памяти содержится во внутреннем каталоге BIOS'а.

На высоком уровне используется обращение по имени модуля, обработка запроса включает в себя поиск имени в каталоге и подстановку физического адреса, поэтому такие запросы выполняются наиболее медленно.

На среднем уровне используется обращение к памяти по логическому номеру сегмента (вся память разбита на сегменты длиной 20000 со сквозной нумерацией, несколько особых сегментов имеют меньшую длину). Такие запросы выполняются намного быстрее, так как отсутствует поиск в каталоге. При образовании модуля, используемого на среднем уровне, (при выделении памяти) необходимо установить признак неперемещаемости и затем с помощью спец. запроса получить фактическое значение логического номера сегмента.

На низком уровне используется обращение по коду режима и физическому адресу, что максимально быстро в рамках BIOS'а, но всё равно выполняется 40. чисто подготовительных операций (сохранение и восстановление регистров, вектора 4, блокировка СТОП, распознавание запроса и переключение режимов) + до 20. операций извлечения и контроля аргументов.

Поэтому в тех случаях, когда действительно нужна высокая скорость обращения к доп. памяти и при этом нельзя разместить используемые процедуры и данные просто внутри одного модуля, нужно вначале по запросу подключать требуемый модуль, затем работать с ним напрямую (по возможности без переключений), в конце возвращаться в исходный режим. Для максимально быстрого переключения режимов и страниц памяти служит особый запрос "сверхнизкого" уровня CH$WRK, который практически ничего не сохраняет и не проверяет, только переключает режим и передаёт управление, да ещё вписывает код нового рабочего режима в специальную ячейку @WRK$, что совершенно необходимо (для корректных возвратов) в том случае, если в процессе работы в новом режиме используются какие-либо запросы или могут происходить внешние прерывания, переключающие режимы. (При возвратах из других страниц и режимов код текущего рабочего режима извлекается из специального стека, расположенного внутри RAM-BIOS, ячейка WRK$ - указатель этого стека; в запросе CH$WRK - 19. операций, включая "BEQ", "JMP".)

При всех запросах, кроме оговорённых отдельно, стек не должен находиться выше 100000. Для выполнения этого условия рекомендуется использование запроса низкого уровня NEW$SP, обеспечивающего корректное образование нового стека.

Запросы высокого и среднего уровней

Запросы высокого и среднего уровней имеют одинаковые точки входа, тип запроса определяется значением старшего байта аргумента, именуемого ниже "NASEG".

NASEG

- аргумент, в котором содержится имя модуля либо логический номер сегмента (=NAME/SEGMENT). Имя модуля (1 слово) представляет собой 2 символа (1-й - старший байт, 2-й - младший!), в старшем байте - идентификатор автора модуля, младший идентифицирует сам модуль. Если старший байт = 0, то это запрос среднего уровня и NASEG = логическому номеру сегмента; номера сегментов 376 и 377 обозначают текущий и DOS-режим соответственно (текущий - режим, из которого пришел запрос, DOS - режим ДОС, в него происходит выход по запросу EXIT$ - см. его описание).

Идентификатор автора модуля введён с целью предотвращения совпадения имён модулей разных авторов, список "занятых" знаков приведён в приложении 5 (просьба к программистам сообщать в АльтПро о "занимаемых" ими знаках).

ADRSME

- смещение от начала модуля, если это запрос высокого уровня, или от начала сегмента, если это запрос среднего уровня; если NASEG = 376 или 377, то ADRSME - физический адрес.

Описанные ниже запросы сохраняют R3-R5, остальные регистры, если это не оговорено отдельно, не сохраняются.

При вызове подпрограмм BIOS можно использовать только абсолютную адресацию!

1. Копирование или обмен массивов ( MOV$G )

        MOV     #ADRSME1,R0
        MOV     #ADRSME2,R1
        MOV     #LEN,R2
        JSR     R5,@#MOV$G      ;@#167520
        .WORD   NASEG1,NASEG2

Под номером 1 - массив-источник, под номером 2 - приёмник.

Отрицательное (NEG) значение LEN (длина в словах) обозначает обмен. Т.о., запрос обеспечивает обмен массивов длиной до 200000 байт.

2. Чтение или обмен одного слова ( CHW$G )

        JSR     R5,CHW$G        ;@#167517
        .WORD   ADRSME,NASEG

Обмен происходит с регистром R0; R1 - флаг (0 - обмен, иначе - чтение). Если R1=0 при выходе - ошибка.

3. Вызов подпрограммы из доп. памяти ( CAL$G )

        JSR     R5,CAL$G        ;@#167516
        .WORD   ADRSME,NASEG

Подпрограмме передаются R3-R5, из подпрограммы возвращаются все регистры. Можно использовать стандартную передачу параметров через стек, нельзя только в подпрограмме использовать адрес возврата (@SP) - он изменён!

На время работы вызываемой п/п блокируются прерывания по вектору 4 (программно - в @#4 заносится #STP$, в @#6 - #200, при возврате восстанавливаются прежние значения), и устанавливается высокий приоритет процессора (при возврате восстанавливается прежний).

Максимальная вложенность подпрограмм в RAM-BIOS v3.01 - 20 (decimal).

Если R1=0 при выходе, то произошла ошибка.

4. Безусловный переход ( JMP$G )

        JSR     R5,JMP$G        ;@#167515
        .WORD   ADRSME,NASEG

Аналогично блокируются прерывания по вектору 4 и устанавливается высокий приоритет процессора.

Если произошёл выход, то была ошибка, при этом R1=0.

5. Работа с каталогом, создание, удаление модулей и др. ( CAT$ )

        MOV     #NUMBER,R0      ;номер функции
        JSR     R5,@#CAT$       ;@#167521

R0=0 - создание модуля (создание записи о модуле в каталоге).

Аргументы:

R1

- адрес записи, которую нужно занести в каталог (формат этой записи такой же, как у записи в каталоге - см. приложение 3; расположена она должна быть в основном ОЗУ - ниже 100000);

R2

- код требуемого сегмента (см. прил. 2.2), если нужен определённый сегмент, или 0 - любой. В процессе обработки R2 очищается по маске #74000;

Следующие 2 параметра "предлагаемой" записи, а также признак #20, учитываются только при установленном бите #4 в <признаках> (см. прил.3). Это:

Если после выхода R0=0, то модуль не создан из-за недостатка памяти или переполнения каталога. Если R0<0 - модуль под таким именем уже есть.

R0=2

- безусловное удаление модуля (без проверки признаков и запуска END-2), в конце - переход к функции номер 6.

Вход: R1 - имя модуля; R0 сохраняется.

R0=4

- то же, но с вызовом END-2.

Если в запросах #2 и 4 после выхода R2=0 - ошибка.

R0=6

- цикл удаления модулей, у которых отсутствуют родительские модули и которые не запрещено удалять в этом случае. R0, R2 сохраняются.

R0=10

- чтение/запись слова каталога (через R1); после команды (JSR R5,@#CAT$) ещё два слова: имя, смещение (последнее – в записи каталога, см. ниже). Если в смещении установлен бит #100000, производится запись, иначе - чтение. Если R0 равен нулю после выхода - ошибка.

R0=12

- возвращает информацию о RAM-BIOS. R0 - номер версии. Текущая версия - 3.05 (#305). R1 - физический адрес начала каталога модулей (он находится по данному адресу в системной странице в SYS-режиме, код включения = #2160), R2 - кол-во записей в каталоге.

R0=16

- получение кода режима и адреса для обращения на низком уровне. Сохраняется R0. После команды (JSR R5,@#CAT$) ещё 2 слова: смешение, имя. Выход: R1 - физический адрес, R2 - код режима (из числа тех режимов, которые в двойной рамке в табл.1). Если R2=0 - ошибка.

Общеупотребительные запросы низкого уровня

6. Сохранение области основной памяти ( SAVE$ )

        JSR     R5,@#SAVE$      ;@#167530

Вход: R0 - адрес вершины (т.е. адрес над областью); R1 - длина (вниз), байт; стек может быть в доп. памяти ( SP>100000 ).

Нормальный выход: R0,R1 не портятся. Нет места для сохранения: R0=0. Сохранение производится во внутреннем стеке сохранения RAM-BIOS, общий его объём в версии 3.01 - 1000 с небольшим байт.

Сохранение и восстановление (в резидентных программах) должно быть в одном вызове (прерывании), иначе может нарушиться порядок (LIFO: Last In - First Out).

7. Восстановление области памяти, сохранённой по SAVE$ (RESTO$)

        JSR     R5,@#RESTO$     ;@#167531

Регистры не портит, стек может быть в дополнительной памяти.

8. Создание нового стека в основном ОЗУ с его (ОЗУ) сохранением ( NEW$SP )

Вызов:

либо:

либо:

JSR R5,@#NEW$SP
.WORD   TOP
.WORD   LEN
MOV #TOP,R0
JSR R5,@#NEW$SP+2
.WORD   LEN
MOV #TOP,R0
MOV #LEN,R1
JSR R5,@#NEW$SP+4

NEW$SP=167630;

TOP

- адрес вершины нового стека (адрес над стеком);

LEN

- длина, байт (вниз) (для сохранения ОЗУ)

Старый стек может располагаться в доп. памяти (выше 100000).

НОРМАЛЬНЫЙ ВЫХОД:

разряд Z=0 (т.е. "не 0"), R0 не равно 0;

SP = #TOP-2, @SP = <прежний SP>; портит R0,R1.

НЕТ МЕСТА ДЛЯ СОХРАНЕНИЯ:

Z=1, R0=0, SP и R1 не изменяются.

Сохранение области ОЗУ происходит по SAVE$ (см. выше) во внутреннем буфере BIOS'а стекового типа, его размер - 1000 с небольшим. При создании нового стека необходимо дополнительно резервировать min 44 байта в связи с дребезгом СТОП (наблюдался случай, когда прерывание по вектору 4 успевало произойти 8 раз, после чего подряд 8 RTI и т.д.).

Возврат в старый стек с восстановлением ОЗУ:

        MOV     @SP,SP
        JSR     R5,@#RESTO$     ;@#167531

9. Быстрая установка/чтение кода текущего режима с передачей управления ( CH$WRK )

Вызов:

либо:

либо:

JSR R5,@#CH$WRK
.WORD   mode
.WORD   addr
MOV mode,R0
JSR R5,@#CH$WRK+2
.WORD   addr
MOV mode,R0
JSR R5,@#CH$WRK+4

3-й вариант - без передачи управления (т.е. с возвратом на следующий за "JSR" адрес).

CH$WRK=167734;

ВХОД:

при mode <= 0 производится только считывание кода текущего режима (в R4) без установки нового, на передачу управления это не влияет;

ВЫХОД:

R4 = код текущего режима до выполнения CH$WRK; R5,R0 портятся (R0=177130).

Ничего не проверяет, не блокирует прерывания, не пользуется стеком (кроме первых 2-3 команд ещё до переключений режимов - т.е. нормально работает, даже если в новом режиме SP будет указывать на ПЗУ).

В подключаемом режиме в сегменте 160000... должен присутствовать ROM-BIOS.

10. Завершение работы программы и выход в ДОС ( EXIT$ )

        JSR     R5,@#EXIT$      ;@#167527

Инициализирует RAM-BIOS (в частности, очищает стек возвратов из подпрограмм, вызванных по запросам CAL$G и CAL$N) и выходит в режим "DOS", обычно на 100000 (см. прил.6). Таким образом, обеспечивается корректный выход в ДОС из любого режима. Также очищает стек сохранений (используемый запросами SAVE$ и NEW$SP).

Кроме того, удаляются модули, у которых установлен признак удаления по EXIT$, а также все модули, у которых отсутствует родительский модуль и при этом их удалять не запрещено ("удаление мусора").

Прочие запросы низкого уровня

11. Пересылка или обмен массивов ( MOV$N )

        MOV     sadr,R0         ;адрес источника
        MOV     dadr,R1         ;адрес приёмника
        MOV     n,R2            ;длина массива - n слов
        JSR     R5,@#MOV$N      ;@#167526
        .WORD   smod,dmod       ;коды режимов источника,приёмника

Длина массива меньше 0 (NEG) означает обмен массивов, иначе - пересылка.

Коды режимов - это коды подключения режимов и страниц (см. прил.1) + флаги:

#100000

- "любой режим" (устанавливать, если массив в основном ОЗУ или ПЗУ);

#40000

- устанавливать, если в этом режиме в сегменте 160000... отсутствует ROM-BIOS (ПЗУ или его копия); в этом случае пересылка производится без обращения к ROM-BIOS (п/п пересылки - в стеке);

Код режима = 0 означает текущий рабочий режим (берётся из ячейки @WRK$ - при штатном использовании запросов BIOS, включая CAL$.., JMP$.., эта ячейка всегда содержит код текущего режима). Правильность установки флагов режимов не контролируется.

Все регистры сохраняются. Стек должен быть ниже 100000. Перекрытие массивов приведёт к ошибке, если приёмник выше источника. Если заданы несовпадающие режимы и отсутствует флаг #100000, пересылка ведётся через основное ОЗУ (с адреса = SP) с его сохранением, перекрытия и пересылка из ПЗУ в этом случае недопустимы.

12,13. Чтение и обмен слов ( RDW$N и CHW$N )

    JSR     R5,@#RDW$N или @#CHW$N      ;@#167524 или @#167525
    .WORD   addr, mode & flags

Читает слово в R0 или обменивает с R0.

Флаги и 0 означают то же, что и в MOV$N. В случае установки флага #40000 чтение и обмен производятся в несколько раз медленнее, чем без него.

14,15. Вызов подпрограммы и безусловный переход (CAL$N и JMP$N)

    JSR     R5,@#CAL$N или @#JMP$N      ;@#167522 или @#167523
    .WORD   addr,mode

В отличие от предыдущих запросов учитывается только реальный код режима и страницы (флаги и 0 не интерпретируются); CAL$N и JMP$N применимы только для тех режимов и страниц, в которых в сегменте 160000... есть ROM-BIOS.

Подпрограмме передаются и из подпрограммы возвращаются все регистры. Можно использовать стандартную передачу параметров через стек, нельзя только в подпрограмме использовать адрес возврата (@SP) - он изменён!

На время работы вызываемой по CAL$N п/п блокируются прерывания по вектору 4 (программно - в @#4 заносится #STP$, в @#6 - #200, при возврате восстанавливаются прежние значения), и устанавливается высокий приоритет процессора (при возврате восстанавливается прежний).

Максимальная вложенность подпрограмм в RAM-BIOS v3.01 - 20.

16-18. Точки входа переключения режимов ( MOD$, MOD$S, MOD$J )

Подключение режима R4

( @#167754 ):

Подключение системного
 режима (с RAMBIOS)

( @#167744 ):

Подключение режима
R4 & JMP

( @#167752 ):

JSR R4,@#MOD$
JSR R4,@#MOD$S
JSR  R4,@#MOD$J
.WORD  ADDR

После физического переключения режима обращения к стеку отсутствуют, регистры (кроме R4) не портятся.

Приведённые запросы не меняют @WRK$ (код текущего режима на вершине стека возвратов), программисты должны сами заботиться о том, чтобы при переключённом режиме не было прерываний (так как возврат из прерываний, переключающих режимы, будет происходить в режим @WRK$ - а он другой).

Приведённые запросы выполняют только переключение и не содержат "лишних" операций, см. поставляемые в комплекте с документацией исходники.

Использование стека запросами BIOS

В процессе обработки запросов BIOS (только вызываемых по "JSR R5,...", кроме CH$WRK) стек опускается на следующую глубину:


Приложение 1. Режимы работы и распределение памяти.

Память в контроллерах "АльтПро" разбита на страницы по 32 Кб, части (сегменты) одной такой страницы подключаются в области адресов 100000-177777, сегменты разных страниц одновременно подключить нельзя. Сегментами ниже называются фрагменты памяти по 10000 байт. Сегмент с номером X=0...7 может быть подключён либо с адреса 1X0000, либо с адреса 1X0000±40000 в зависимости от номера режима.

Распределение памяти в различных режимах приведено в табл.1, затем следуют пояснения общего характера, которые рекомендуется прочитать, и примечания специального характера, которые понадобятся тем, кто пишет некорректные программы; тем, кто пишет корректные программы, рекомендуем пользоваться запросами BIOS, значительно упрощающими работу с доп. памятью и предотвращающими конфликты.

Таблица 1. Режимы работы и распределение памяти.

Название режима

SYS

Std10

ОЗУ10

All

Std11

ОЗУ11

Hlt10

Hlt11

Код включения

160

60

120

20

140

40

100

20000

Вырабатываемые сигналы

Откл.монитора БК10

   

+

+

   

+

+

Откл.монитора БК11М

 

+

 

+

 

+

 

+

Откл. верх.ОЗУ-11М

+

+

+

+

       

АДРЕСА

номера подключаемых сегментов

HDD: 170-177000

ПЗУ

7

7

3

7

7

7

7

170(177000hdd)-0

ПЗУ

-

7W/-

3R

-

-

7W

7W

160000-170000

ПЗУ

ПЗУ

6

2

ПЗУ

6

6R/6

6

150000-160000

1

5

5

1

-

5

5

5

140000-150000

0

4

4

0

-

4

4

4

130000-140000

7

3

3

7

-

-

3

-

120000-130000

6

2

2

6

-

-

2

-

110000-120000

-

-

1

5

-

-

1

-

100000-110000

-

-

0

4

-

-

0R

-

ПОЯСНЕНИЯ

Буква 'W' после номера сегмента означает, что ОЗУ доступно только по записи, 'R' - только по чтению, через дробную черту - старая версия контроллеров / новая (по номеру версии ПЗУ не определяется), '-' - не подключается ничего.

ПЗУ в контроллерах имеет объём 10000 байт, в режиме SYS одно и то же ПЗУ подключается и со 160000, и со 170000 (благодаря этому изменяется адрес запуска компьютера).

В контроллерах "SMK" ("винтовых") во всех режимах, кроме SYS, в адресах 170000-177000 подключено ОЗУ, в дисководных - нет, выше 177000 - во всех одинаково.

Внутри таблицы в рамки выделены группы режимов и адресов, используемые при пересылке данных для доступа ко всем 8 сегментам страницы памяти (одна рамка для БК10, другая - БК11М: это области, неперекрывающиеся с ПЗУ и охватывающие всю страницу). Однако при размещении и вызовах подпрограмм на БК11М RAM-BIOS использует два первых режима (SYS и Std10) в окне 120000-140000, т.к. для работы с подпрограммами необходимо наличие ROM-BIOS в адресном пространстве.

РАСШИФРОВКА РЕЖИМОВ:

SYS - используется для запуска, пересылки данных на БК10 и RAM-BIOS'ом (он - всегда в 0-й странице);

Std10, Std11 - стандартные, традиционные режимы работы для БК10 и 11М соответственно, Std10 используется также для пересылки данных на БК10;

ОЗУ10 - вместо монитора БК10 и ПЗУ-160000 подключается ОЗУ (на многих БК10 требуется простая доработка, иначе доп. ОЗУ подключается параллельно ПЗУ монитора и приходится записывать в это ОЗУ копию монитора); используется также для доступа к доп. памяти на БК11М;

All - позволяет на БК10 подключить ОЗУ ко всему адресному пространству, что используется для загрузки копии Вильнюсского Бейсика; применяется также для доступа к доп. памяти на БК11М;

ОЗУ11 - подключение ОЗУ вместо ПЗУ на БК11М, для отключения ПЗУ монитора БК11М простая доработка требуется всегда;

Hlt10, Hlt11 - открывают доступ к HALT-режиму процессора на БК10 и БК11М соответственно. Максимально "продвинутые" режимы: везде, где можно, подключается ОЗУ вместо ПЗУ и на БК10 нижняя часть ОЗУ монитора защищена от записи (квази-ПЗУ) для повышения глюкоустойчивости.

Доработки для отключения ПЗУ монитора описаны в файле "СХЕМЫ.EDP".

На контроллерах с доп. ОЗУ менее 256 Кб на БК10 может быть подключено ПЗУ Бейсика традиционно записью #10 в 177130, правда на режимы ОЗУ это никак не влияет.

При подключении ОЗУ параллельно чему-либо (ПЗУ, регистры) в случае конфликта данных (в одном - 0, в другом - 1) в подавляющем большинстве случаев читается 1 (для микросхем такой конфликт не страшен, все они имеют внутреннюю защиту - хотя, конечно, конфликты снижают помехоустойчивость и потому нежелательны). Поэтому при параллельном подключении ОЗУ и ПЗУ в ОЗУ надо предварительно записывать копию ПЗУ, а при параллельном подключении ОЗУ и регистров в ОЗУ должны быть нули.

При включении режима "All" из режимов Hlt10, Hlt11 (а на "старых" контроллерах ещё и из режима ОЗУ10) в ОЗУ режима "All" по адресу 177130 вписывается <20 + код страницы>; при использовании запросов BIOS таких переключений не бывает.

КОДЫ ПОДКЛЮЧЕНИЯ СТРАНИЦ ОЗУ:

64 Кб -

0,2000;

128 Кб -

0,2000,4,2004;

256 Кб -

0,2000,4,2004,10,2010,14,2014;

512 Кб -

0,2000,4,2004,10,2010,14,2014,
1,2001,5,2005,11,2011,15,2015.

Объём памяти можно определить по байту 167777 ПЗУ контроллера (см. приложение 4).

При переключениях коды режима и страницы необходимо складывать по BIS.

Приложение 2.1 Формат таблицы сегментов BIOS.

Вся память разделена на сегменты длиной 20000 (несколько особых сегментов имеют меньшую длину). Соответствие логических номеров физическим кодам сегментов задано в таблице, где каждый сегмент описывается одним словом. Адрес таблицы можно получить следующим образом после запроса CAT$ (вызов #12, результат в R1) при условии подключения страницы с RAM-BIOS'ом:

        SUB -(R1),R1
        MOV (R1)+,R2        ;R2 - кол-во сегментов
                            ;R1 - адрес начала таблицы

Кроме кода режима и кода страницы, которые мы упоминали ранее (см. также прил. 2.2), используются следующие биты:

#100000

- сегмент подключается с адреса @#120000, иначе - с адреса 100000 на БК11М, 140000 - на БК10. На БК11М означает также, что при используемом в BIOS подключении этого сегмента одновременно с ним будет подключено и ПЗУ (т.е.

будет доступен ROM-BIOS - используются режимы с кодами 160 и 60). Для размещения программ на БК11М используются именно такие сегменты, так как нужен доступ к ROM-BIOS.

#40000

- длина сегмента меньше на #10000 (есть два стандартных случая установки этого бита: 10000 над RAM-BIOS'ом и 10000 перед 4 Кб с таблицей разделов).

#20000

- вычитание из длины сегмента #650 (т.е. 177130-177777).

#10000

- вычитание из длины сегмента #350 (для модема без винчестера в HALT-режиме, устанавливается совместно с битом #20000).

#4000

- начало сегмента смещено на 10000 (устанавливается совместно с битом #40000).

Приложение 2.2 Коды сегментов, используемые в BIOS.

Физические номера сегментов согласно табл.1 приложения 1

Для БК10

Для БК11М

0, 1

160 + код.страницы

20 + код.стр.

2, 3

100060 + код.страницы

100120 + код.стр.

4, 5

60 + код.страницы

120 + код.стр.

6, 7

100160 + код.страницы

100020 + код.стр.

Приложение 3. Формат записи каталога модулей.

Запись каталога имеет следующую структуру:

00

слово

<имя>

- 1-й байт - идентификатор автора модуля (старший байт), байт=#0 используется для служебных целей; 2-й байт - идентификатор модуля;

02

слово

<длина в словах>

- меньше 100000 (в словах);

04

слово

<признаки>:

#1

- можно удалять при нехватке памяти (пока не используется);

#2

- модуль нельзя перемещать (0 - можно). Необходимо устанавливать, если есть обращения к модулю на среднем или низком уровне;

#4

- нельзя разбивать модуль на части (размещать в разных сегментах), 0 - можно;

#10

- удалять модуль по запросу EXIT$ или перезапуску, 0 - да;

#20

- возможность запуска модуля (1 - да; актуально для модулей, содержащих программы). Установка этого признака приводит к размещению с адреса 120000 до 140000, что актуально для БК11М (см. прил. 2.1), на БК10 этот бит предпочтительно не устанавливать;

#40

- подлежит удалению, если родительский модуль в памяти (в каталоге) отсутствует ( 1 - да), реально автоматическое удаление таких модулей производится при запросах EXIT$, CAT$ при R0=#2,4,6, и сделано это для автоматического удаления мусора;

#100

- перед удалением модуля запускать END-2 (по CALL);

#200

- есть расширенное имя внутри модуля (см. слово 10);

06

слово

<имя родительского модуля>

- формат такой же, как и у слова 00; задаётся программистом при создании модуля; 0 - не определено - при удалениях равносильно тому, что родительский модуль всегда есть;

10

слово

<смещение до расширенного имени>

- смещение от начала модуля до текста .ASCIZ;

12

слово

<смещение>

- смещение от начала сегмента до начала модуля;

14

байт

<сегмент>

- логический номер сегмента начала модуля;

15

байт

<резерв>.

 

Приложение 4. Кодировка версии контроллера.

Номер версии доступен программно - он содержится в последнем слове ПЗУ (по адресу 167776). В старшем байте содержится ключ и информация об объёме дополнительной памяти, в младшем байте - информация о типе контроллера и номере версии ПЗУ.

174000

- A16;

174400

- A16 + контроллер "винта" с доп. ОЗУ 4 Кб (170-177000);

175000

- A16M;

175400

- не используется;

   

если младший байт > 0 - то это старая версия ПЗУ совмещённого контр. винчестера и дисковода SMK64 - её нужно заменить (ПЗУ установлено на панелях); если млад. байт имеет значение от 200 до 300 - то это контроллер SMK, если > 300 - это дисководный контроллер A64M-A512M.

176000

- 64 Кб

176400

- 128 Кб

177000

- 256 Кб

177400

- 512 Кб

В старой версии ПЗУ ( мл. байт > 0 ) ROM-BIOS отсутствует.

Проверка на наличие не менее 64 Кб и современной версии ПЗУ осуществляется одной командой: CMP @#167776,#176200 \ BHIS - Ok

Внимание! Программисты, загружающие в ОЗУ с адреса 160000 свою версию драйверов, должны область 167460-170000 (точки входа BIOS и номер версии контроллера) копировать 1:1 из ПЗУ !

Приложение 5. Зарезервированные знаки в именах модулей.

Для старшего байта имени модуля (идентификатор изготовителя) по состоянию на 1.06.98 г. зарезервированы следующие знаки:

$ % `(обратный апостроф) R L

Программисты, желающие закрепить за собой какой-либо другой символ, должны сообщить об этом в фирму-изготовитель (АльтПро) для предотвращения совпадений и программных конфликтов.

Приложение 6. Стек возвратов и режим DOS.

Стек возвратов из подпрограмм, вызываемых по запросам CAL$G и CAL$N растёт вниз (каждый CAL$ добавляет в стек 4 слова), в исходном состоянии (после загрузки или EXIT$) представляет собой следующее:

TOP:

<код режима (DOS)>

- код исходного режима, того, в котором работает ДОС с оболочкой; изначально это Std10 или Std11, т.е. стандартный режим БК10 или 11М, коды 60 или 140; если программа перемещает ДОС в другой режим (например, Halt10 или Halt11), то она должна корректировать и эту ячейку (см.ниже);

TOP-2:

< old PC >

- псевдо-адрес возврата - 100000;

TOP-4:

<PS & @#6>

- здесь - 0;

TOP-6:

< @#4 >

- копия ячейки 4 для её восстановления - 100442;

TOP-10:

<код текущ. режима>

- при запуске и EXIT$ устанавливается = коду режима DOS, указатель WRK$ устанавливается = TOP-10 (таким образом, WRK$ указывает на ячейку с кодом текущего режима).

Указатель стека возвратов WRK$, адрес = 120016 в системной странице (код её включения - #2160), после запуска или EXIT$ содержит #TOP-10, при каждом CAL$ он опускается на 10; ячейка DOS$ (адрес 120020 в системной странице), введённая для доступа к коду DOS-режима, всегда содержит #TOP.

После первого CAL$ (стек возвратов опускается на 10):

TOP-10:

<код предыдущего режима>

- код режима, из которого был CAL$;

TOP-12:

<old PC>

- адрес возврата;

TOP-14:

<PS & @#6>

- сохранённые слово состояния процессора и @#6;

TOP-16:

< @#4 >

- сохранённая при запросе CAL$ ячейка 4;

TOP-20:

<код текущ. режима>

- код нового режима.

При включении питания компьютера и при перезапуске без логической обработки включается стандартный режим (Std10 или Std11), в нем обычно загружается ДОС, и он же объявляется режимом "DOS" при инсталляции RAM-BIOS. Однако в дальнейшем в ряде случаев (например, при подключении HALT-режима), DOS-режим меняется программами типа WINDOWS, OS/A, HALT-DRIVER. Короче, программисты могут изменять содержимое ячеек TOP - TOP-6, используя доступ через ячейку DOS$.

Приложение 7. Обработка ошибок.

В случае возникновения ошибки BIOS вписывает код ошибки в байт ERR$ = 120004 в системной странице (код её включения - #2160) при условии, что RAM-BIOS в этой странице имеется, после чего выдаёт сигнал ошибки - характерное затухающее подёргивание экрана с прерывистым звуковым сигналом.

Признак наличия RAM-BIOS: в ячейке 120010 системной страницы содержится #120012.

Коды ошибок (на 1.06.98 г.):

#100

- разрушен конец RAM-BIOS;

#1

- несуществующий запрос BIOS;

#2

- нарушение или переполнение стека возвратов; переполнение фиксируется при CAL$, если адрес в ячейке WRK$ (120016) ниже, чем содержимое WRKLIM (120014);

#340

- ошибка при попытке восстановления области памяти по RESTO$ (нарушение стека сохранения).

Признак целостности байта ERR$: байт 120005 = 111 (octal).

Приложение 8. Стандартные адреса и константы BIOS.

1) В области ROM-BIOS:

BEGIN$=167342   ;начало ROM-BIOS; здесь располагаются подпрогра-
                ;ммы пересылки массивов, стандартное обращение к
                ;которым бывает только при  подключенном  ПЗУ  -
                ;поэтому при переносе ROM-BIOS в ОЗУ  эту  часть
                ;можно не копировать;
BEG$R5=167460   ;начало точек входа запросов BIOS - эту часть  и
                ;всё, что ниже, при переносе ROM-BIOS в ОЗУ нуж-
                ;но копировать;
STP$=167712     ;стандартная подпрограмма блокировки кнопки СТОП
ARTI$=167714    ;в этой ячейке находится команда RTI
DIR1$=167720    ;3 "прямых" точки входа (не по JSR R5,...) - на-
DIR2$=167724    ;пример, для обработки прерываний в доп. ОЗУ;  в
DIR3$=167730    ;версии RAM-BIOS 3.05 - не задействованы: для их
                ;использования надо поместить адрес  обработчика
                ;пользователя в  таблицу  подпрограмм  обработки
                ;запросов в системной странице...
MOD$S=167744    ;3 точки входа переключения  режимов  на  низком
MOD$J=167752    ;уровне (используются при заблокированных преры-
MOD$=167754     ;ваниях;
VERS$=167776    ;номер версии ПЗУ и код контроллера
 
JMP$G=167515    ;ТОЧКИ ВХОДА ЗАПРОСОВ по  JSR R5,@#_имя_
CAL$G=167516
CHW$G=167517
MOV$G=167520
CAT$=167521
CAL$N=167522
JMP$N=167523
RDW$N=167524
CHW$N=167525
MOV$N=167526
EXIT$=167527
SAVE$=167530
RESTO$=167531
NEW$SP=167630
CH$WRK=167734

2) В области RAM-BIOS (в системной странице доп. ОЗУ):

R$VERS=120002   ;содержит номер версии RAM-BIOS;
ERR$=120004     ;мл.байт - код ошибки, ст.байт = 111;
PZP$=120006     ;содержит адрес подпрограммы  обработки  нестан-
                ;дартного перезапуска;
CTRL0$=120010   ;содержит #120012 - по этой константе проверяет-
                ;ся целостность начала RAM-BIOS;
MAIN$=120012    ;содержит адрес диспетчера запросов;
WRK$=120016     ;указатель стека режимов
DOS$=120020     ;указатель на ячейку с кодом DOS-режима

Приложение 9. Краткие сведения о HALT-режиме.

Необходимым условием работы HALT-режима является наличие ОЗУ по записи по адресу 177674, где в 2 последовательных ячейках сохраняется PC и PS при HALT-прерывании. Кнопка СТОП всегда вызывает именно это прерывание, но из-за отсутствия указанного ОЗУ вслед за HALT-прерыванием происходит прерывание по вектору 4 (причём, в результате этого PC в стеке оказывается на 2 больше, чем надо).

HALT-прерывание происходит по вектору 160002, совместить это с драйвером дисковода возможно, подключив со 160000 ОЗУ вместо ПЗУ (см. реализации WIN-DEMO и OS/A WASP).

В ячейке 160004 (new PS) должен быть установлен бит #2000 - "высокий приоритет процессора для HALT-режима" - чтобы заблокировать прерывания от дребезга кнопки СТОП, и обработчик HALT-прерывания должен некоторое время не делать никаких операций, изменяющих PS, поскольку при "обычных" операциях бит #2000 в PS всегда сбрасывается.

Итак, алгоритм обработки HALT-прерывания в программах типа WIN-DEMO, OS/A WASP (работающих по СТОП+клавиша) в первом приближении (ориентировочно!) следующий:

  1. Задержка против дребезга СТОП и против запаздывания появления признака нажатой клавиши (последнее случается величиной до 40000 SOB'ов при 6 МГц - от момента нажатия).
  2. Переключение режимов и извлечение адреса возврата и PS.
  3. Команда по <адресу возврата - 2> вызывает HALT-прерывание (0 и ещё кое-какие)? Если да, то сэмулировать прерывание по век тору 4.
  4. Клавиша нажата? Если нет, то прибавить 2 к адресу возврата и сэмулировать прерывание по вектору 4.
  5. Собственно обработка прерывания.

 

(с) В.Е.Новак, А.И.Глускер 1997-98 гг.