1431

Система управления и контроля радиоприемным устройством

Дипломная

Информатика, кибернетика и программирование

Обеспечение функционирования вычислительного комплекса, обнаружения сбоев и отказов модулей и горячего восстановления. Требования к организации и оборудованию рабочих мест с ПЭВМ для взрослых пользователей. Команды буфера интерфейсной информации.

Русский

2013-01-06

1.07 MB

31 чел.

  1.  

Министерство образования Российской Федерации

САНКТ - ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

Кафедра "Системный анализ и управление"

Проект допущен к защите

Зав. кафедрой                  

__________________ В. Н. Козлов

__________________  2008 г.

ДИПЛОМНАЯ РАБОТА

Тема:

Направление 654700 – Информационные системы

Выполнил: студент гр. 6082.1 Шевченко Андрей Владимирович

Руководитель: к.т.н., доцент Баранов Виктор Ефимович

Консультанты:

По экономической части

( уч. степень, должность)………………………………………..Ф.И.О.

По вопросам охраны труда

( уч. степень, должность)………………………………………..Ф.И.О.

Санкт-Петербург

2008


РЕФЕРАТ

Данная дипломная работа по теме «Система управления и контроля радиоприемным устройством» содержит:

листов 225

разделов 7

рисунков 3

Ключевые слова:

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


Содержание

ВВЕДЕНИЕ 6

1 Постановка задачи 8

1.1 Требования к работе 8

1.2 Анализ средств разработки 8

1.3 Выбор языка программирования 8

2 Архитектура вычислительного комплекса 9

2.1 Архитектура центрального вычислителя 9

2.2 Архитектура автоматизированного рабочего места 10

3 Архитектура процессора 12

3.1 Узлы процессора 12

3.2 Регистры 12

3.2.1 Регистры буфера интерфейсной информации 12

3.2.2 Регистры арбитра 13

3.2.3 Регистры АЛУ 14

3.2.4 Регистры сдвигателя 14

3.2.5 Регистры контроллера прерываний 15

3.2.6 Регистры МУС 16

3.2.7 Регистры РОН 16

3.2.8 Регистры УКС 17

3.2.9 Регистры таймера 17

4 Язык микропрограммирования 18

4.1 Общие сведения 18

4.2 Элементы языка 19

4.3 Общая структура микропрограммы 20

4.4 Метки 21

4.5 Оформление файлов описания микропамяти 24

4.6 Символические константы 24

4.7 Циклы 25

4.8 Операции, составляющие описание микрокоманды 25

4.9 Команды узлов процессора 26

4.9.1 Команды БМУ 26

4.9.2 Команды коммутатора адреса микрокоманды 27

4.9.3 Команды АЛУ 28

4.9.4 Команды сдвигателя 29

4.9.5 Команды УКС 29

4.9.6 Команды МУС 30

4.9.7 Команды контроллера прерываний 31

4.9.8 Команды таймера 31

4.9.9 Команды буфера интерфейсной информации 32

4.9.10 Команды анализаторов 33

4.9.11 Совмещенные команды 33

4.10 Операторы 34

4.11 Выражения 35

5 Обеспечение надежности 37

5.1 Основные термины 37

5.2 Аппаратные методы 39

5.3 Микропрограммные методы 43

5.4 Программные методы 52

5.5 Динамика работы 59

5.5.1 Тупик 59

5.5.2 Аппаратная реакция на ошибки 59

5.5.3 Ошибка процессора 59

5.5.4 Ошибки ОЗУ 60

5.5.5 Ошибки зависания и четности при работе с внешними устройствами 60

6 Безопасность жизнедеятельности 61

6.1 Анализ опасных и вредных факторов, выявленных на рабочем месте, при работе с ПЭВМ 61

6.1.1 Требования к визуальным параметрам ВДТ, контролируемым на рабочих местах 63

6.1.2 Психофизиологические нагрузки 63

6.2 Обеспечение безопасности рабочего места оператора при работе с ПЭВМ 64

6.3 Общие требования к организации рабочих мест пользователей ПЭВМ 64

6.4 Требования к организации и оборудованию рабочих мест с ПЭВМ для взрослых пользователей 66

6.5 Искусственное освещение помещения 68

6.6 Выводы 73

7 Экономико-организационная часть 74

7.1 Выбор аналога объекта разработки 74

7.2 Определение товарного типа объекта разработки 74

7.3 Определение трудоемкости выполнения разработки 74

7.4 Расчет сметы затрат на разработку 75

ЗАКЛЮЧЕНИЕ 82

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ 83

ПРИЛОЖЕНИЯ..........................................................................................85


  1.  ВВЕДЕНИЕ

Задача обеспечения надежности вычислительной техники остро стоит во многих областях деятельности человека, в частности в оборонной промышленности. Решена она может быть как с помощью увеличения наработки на отказ, так и использованием резервирования. Резервирование разделяется на «горячее», когда резервный элемент работает наряду с основным, и скользящее («холодное»), когда резервный элемент выключен, а включается только после отказа основного. В рассматриваемом вычислительном комплексе используется горячее резервирование с восстановлением.

Условиями приближенного расчета надежности восстанавливаемых изделий и систем являются следующие положения:

1) время восстановления намного меньше времени наработки элемента на отказ. В рассматриваемом ВК время наработки на отказ измеряется тысячами часов, время восстановления ОЗУ – десятками секунд, а время восстановления процессора – миллисекундами (после замены отказавшего модуля);

2) интенсивность отказов и восстановлений – постоянные величины. В данном ВК реализована защита от внешних воздействий (температуры, влажности, вибрации, радиации), поэтому на интенсивность сбоев и отказов они не влияют. Восстановление модуля происходит сразу после сбоя или отказа, поэтому интенсивность восстановлений также является постоянной величиной.

3) отказы и восстановления отдельных элементов и подсистем – независимые случайные события. В данном ВК отказы и восстановления модулей не влияют на работоспособность других модулей, следовательно, это условие соблюдается.

Цель дипломной работы – обеспечение функционирования вычислительного комплекса, обнаружения сбоев и отказов модулей и горячего восстановления. Расчет параметров надежности в данную работу не входит.


  1.  Постановка задачи
    1.  Требования к работе

В результате данной работы должны быть реализованы микропрограммный и программный компонент вычислительного комплекса. Микропрограммный компонент должен включать:

  •  реализацию языка «ассемблер»;
  •  обработчик прерываний;
  •  средства повышения надежности;
  •  средства сопряжения с отладчиком.

Программный компонент должен обеспечивать тестирование комплекса и взаимодействие с пользователем.

  1.  Анализ средств разработки

Микропрограммные и программные компоненты вычислительного комплекса разработаны на платформе Linux, т.к. Эта операционная система открыто распространяется вместе с исходными текстами. Этот критерий выбора обусловлен требованиями органов сертификации при Министерстве Обороны РФ.

  1.  Выбор языка программирования

Микропрограмма разработана на специализированном языке микропрограммирования, который был разработан для данной аппаратной платформы. Разработка на других языках невозможна.

Программные компоненты разработаны на языке Си, т.к. этот язык является языком высокого уровня и получил наибольшее распространение.


  1.  Архитектура вычислительного комплекса
    1.  Архитектура центрального вычислителя

Рассматриваемый вычислительный комплекс является системой со структурным резервированием. Термин «резервирование» следует понимать как способ обеспечения надежности управления (результата вычислений) путем внесения существенно избыточных элементов. «Структурное резервирование» подразумевает существенную избыточность в структуре вычислителя. В данном случае избыточность выражена наличием троированных устройств – в СВК присутствуют три процессора и три ОЗУ, каждое на своей магистрали. Надежность обеспечивается мажорированием информации в циклах обмена. Термин “мажорирование” подразумевает голосование. Если какое-нибудь из троированных устройств подает на вход мажоритара информацию, не совпадающую с другими двумя устройствами, считается, что это устройство ошиблось. На выход мажоритара выдается правильное (мажорированное) значение, а в регистрах ошибок всех трех процессоров выставляется бит, говорящий об ошибке троированного устройства. Далее этот бит становится причиной прерывания, в процессе обработки которого происходит диагностика вызвавшего ошибку устройства и необходимые действия по исправлению ошибки. Внешние устройства (кроме ОЗУ) не являются троированными, для чтения и записи в них существуют специальные микрокоманды. Обмен с ВУ происходит только по той магистрали, на которой находится устройство.

Рис. 2.1. Архитектура вычислительного комплекса

Одновременная ошибка двух троированных устройств приводит к так называемому тупику – ситуации, когда нельзя решить, какая информация является верной. В этом случае происходит сброс комплекса с последующей перезагрузкой. В случае отказа одного из троированных устройств предусмотрена работа в неполной конфигурации, где ошибка любого из оставшихся устройств приводит к тупику.

  1.  Архитектура автоматизированного рабочего места

Рис. 2.2. Архитектура АРМ

АРМ отличается от ВК меньшим резервированием, и ошибки в нем не могут быть исправлены. Следовательно, любой сбой приводит к перезагрузке АРМ.


  1.  Архитектура процессора
    1.  Узлы процессора

Процессор ПР-077 состоит из следующих функциональных узлов:

  •  блок микропрограммного управления (БМУ);
  •  коммутатор адреса микрокоманды (КОМ);
  •  арифметико-логическое устройство (АЛУ);
  •  сдвигатель (СДВ);
  •  регистры общего назначения (РОН);
  •  блок указателей стека (УКС);
  •  мультиплексор условий (МУС);
  •  контроллер прерываний (ПРЕР);
  •  интервальный таймер (ИТ);
  •  буфер интерфейсной информации (БУФ);
  •  арбитр (АРБ);
  •  кольцо анализаторов (АНАЛ);

Каждый узел имеет свои команды, которые в ЯМП представлены мнемоническим описанием.

  1.  Регистры

После названия каждого регистра в скобках указана разрядность.

  1.  Регистры буфера интерфейсной информации

Ba (24) – буфер адреса;

Bd (32) – буфер данных;

Bd1 (8) – младший байт буфера данных;

Bd2 (16) – младшее полуслово буфера данных;

PIP1 (8) – младший байт конвейера (только чтение);

PIP2 (16) – полуслово конвейера (только чтение);

PC (16) – счетчик команд.

При чтении регистров Pip1 и Pip2 увеличивается значение регистра PC.

  1.  Регистры арбитра

ARB (8) - регистр управления обменом;

Значения ARB при записи:

7

6

5

4

3

2

1

0

Размер данных:

00 – слово

10 – полуслово

01 – байт

Инверсия контроль-ных разрядов

Блоки-ровка

конвей-ера

Блоки-ровка прямого доступа

Обраще-ние к технологи-ческому абоненту

Сброс магист-рали

(инверс-ный)

Запись в РУК

(инвер-сия)

РУК – регистр управления конфигурацией.

Разряды ARB при чтении:

7

6

5

4

3

2

1

0

MonIO

Номер процессора

Mon

Номера процессоров в СВК:

1-й процессор: 0;

2-й процессор: 2;

3-й процессор: 1;

Номера процессоров в АРМ:

1-й процессор: 3;

2-й процессор: 3;

Mon (3) - Номер магистрали для работы с ОЗУ. Разряды Mon:

2

1

0

3-я магистраль

2-я магистраль

1-я магистраль

Значение регистра Mon влияет также на конвейерный обмен.

MonIO (3) - Номер магистрали для работы с ВУ. Разряды MonIO:

2

1

0

3-я магистраль

2-я магистраль

1-я магистраль

  1.  Регистры АЛУ

Q (32) – аккумулятор;

Is (32);

L (32);

G (32);

Rcom (32);

R1 (32);

R2 (32);

R3 (32);

R4 (32);

Alu_F (32) – псевдорегистр – результат последней операции АЛУ;

D (32) – псевдорегистр (только чтение). Соответствующий операнд берется с шины DB во 2-м полутакте;

Z (32) – псевдорегистр (только чтение). Константа ноль.

  1.  Регистры сдвигателя

SD_N – параметр сдвига (32);

SD – сдвигаемое число (32).

  1.  Регистры контроллера прерываний

РОШ (16) – регистр ошибок;

Разряды РОШ:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

ту-пик

переполне-ние в АЛУ

резерв

ошибки нечетности

ошибки зависания на магистралях

ошибки магистралей

ошибки процессоров

РПР (16) – регистр прерываний;

Разряды РПР:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

Тай-мер

Ре-зерв

Конец обмена через ТА

Начало обмена через ТА

Прерывания от внешних устройств

МРОШ (16) – регистр маски ошибок – разрешает прерывания по разрядам РОШ;

МРПР (16) – регистр маски прерываний – разрешает прерывания по разрядам РПР;

RG16 (15) – регистр маски тупика – разрешает тупик по соответствующим разрядам РОШ без учета МРОШ;

RG10 (10) – регистр групповой маски тупика – тупик по соответствующим разрядам РОШ в 2 или 3 процессорах без учета МРОШ;

Разряды RG10:

9

8

7

6

5

4

3

2

1

0

Резерв

Ошибки 3 из 3

Резерв

Ошибки 2 из 3

СВ

ЗАВ

МГ

ПР

СВ

ЗАВ

МГ

ПР

ПР – ошибка процессора;

МГ – ошибка магистрали;

ЗАВ – зависание магистрали;

СВ – свертка (ошибка нечетности на магистрали);

Vector (4) – вектор прерывания (только чтение);

Значения вектора:

0 – резерв

1 – РОШ[14]

2 – РОШ[13]

3 – РОШ[12]

4 – прерывание от внешнего устройства

5 – РПР[12-15]

6 – логическая сумма vector[1 + 5]

7 – логическая сумма vector[1 + 6]

8 – резерв

9 – резерв

A – ошибка процессора

B – тупик по процессору

C – ошибка магистрали

D – тупик по магистрали

E – ошибка процессора и магистрали

F – тупик по процессору и магистрали

  1.  Регистры МУС

Mask (8) – маска условий;

  1.  Регистры РОН

Все регистры 32-х разрядные. Нумеруются от Ron0 до Ron63 (номер соответствует младшим 6 разрядам адреса). Некоторые регистры кроме номера имеют мнемонические обозначения:

Адрес

Название

Адрес

Название

1

1000000

Read Control Reg

17

1010000

Ron R1

2

1000001

Write Control Reg

18

1010001

Ron R2

3

1000010

19

1010010

Ron R3

4

1000011

Ron X

20

1010011

Ron R4

5

1000100

Ron NL

21

1010100

Ron R5

6

1000101

Ron NG

22

1010101

Ron R6

7

1000110

Ron NK

23

1010110

Ron R7

8

1000111

OSI

24

1010111

Ron R8

9

1001000

OSA

25

1011000

Ron R9

10

1001001

OSP

26

1011001

Ron R10

11

1001010

RTS

27

1011010

Ron R11

12

1001011

RCC

28

1011011

Ron R12

13

1001100

Ron L

29

1011100

14

1001101

Ron G

30

1011101

Ron LW

15

1001110

31

1011110

16

1001111

32

1011111

Ron Zero

  1.  Регистры УКС

TopI (6) – указатель вершины стека;

BotI (6) – указатель дна стека;

  1.  Регистры таймера

Все регистры 16-разрядные.

RG1 – счетчик длинного таймера

RG3 – коэффициент умножения длинного таймера

RG4 – короткий таймер

RG5 – таймер гладкого счета (младшее полуслово)

RG6 – таймер гладкого счета (старшее полуслово)

Использование регистров таймера в командах пересылки невозможно. Доступ к ним осуществляется командами таймера.


  1.  Язык микропрограммирования
    1.  Общие сведения

Язык микропрограммирования (далее - ЯМП) является языком программирования нижнего уровня. ЯМП ориентирован на процессор с микропрограммной архитектурой, поэтому его выражения строятся исходя из архитектуры процессора.

Логика микросхем, составляющих процессор, определяется содержимым внутренних регистров схемы и содержимым управляющих входов схемы. Все управляющие входы микросхем собираются в микрокоманду (МК).  Таким образом, МК - битовая шкала, под управлением которой процессор работает каждый такт. МК логически делится на поля - группы управляющих битов для одного кристалла.

Микрокоманды хранятся в ПЗУ либо в статической памяти, которая называется микропамятью; процессор дополняется микросхемой, отвечающей за выбор следующей МК из микропамяти, а в МК добавляются поля, управляющие этой схемой.

Поля тех микрокоманд, которые не описываются явным образом, имеют вполне определенные значения, называемые значениями по умолчанию. Кроме того, если явное описание действий, выполняемых в микрокоманде, не затрагивает каких-либо полей микрокоманды, то эти поля сохраняют значения по умолчанию. Иными словами, можно считать, что есть некоторое содержимое микропамяти, используемое по умолчанию, а описание, выполняемое на языке микропрограммирования, изменяет отдельные его части.

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

  1.  Элементы языка

Для описания ЯМП, как и для описания языков высокого уровня, необходимо ввести базовые понятия, такие как алфавит языка, лексемы, типы данных, операции над данными, правила написания выражений, структура программы.

В алфавит ЯМП входят:

  1.  буквы латинского и русского алфавита: ‘A’, ‘B’ … ‘Z’, ‘А’, ‘Б’…’Я’ все символы независимы от регистра, поэтому последовательность символов ‘aSd’ и ‘ASD’ эквивалентны.
  2.  цифры: 0, 1, …9
  3.  специальные знаки: $ # + “ ‘ , ( ) % ^ & * / - = : < > ;
  4.  символы разделители, используемые для отделения лексем друг от друга: пробелы, знаки табуляции, переходы на новую строку, символ ‘_’.

В тексте программы могут содержаться комментарии. Комментарий – последовательность символов заключенная между специальными знаками. В ЯМП могут использоваться комментарии в стиле языков: Алгол68 (#комментарий в стиле языка Алгол68#), С (/*комментарий в стиле языка С*/) и С++ (//комментарий с стиле языка С++, до первого неотображаемого символа перевода строки).

Из последовательности символов цифр и знаков формируются лексемы. Лексемы - единицы текста программы, которые при компиляции воспринимаются как единое целое. В ЯМП шесть классов лексем: свободно выбираемые идентификаторы, ключевые слова, константы,  строки (строковые константы), операции, разделители (знаки пунктуации).

Идентификаторы – последовательность букв и цифр, символов подчеркивания ‘_’ и пробелов, пробелы и символы подчеркивания не являются значащими символами. Например, последовательности ‘ASD’ и ‘A_S     D’ эквивалентны.

Ключевые слова – идентификаторы, зарезервированные в языке, т.е. такие, которые нельзя использовать в качестве свободно выбираемых идентификаторов. К ним так же относятся идентификаторы, начинающиеся с точки ‘.’.

Константы - В описании микропамяти на ЯМП могут использоваться константы двух видов: десятичные и шестнадцатеричные. Шестнадцатеричные константы выглядят следующим образом: $<последовательность шестнадцатеричных цифр> или 16r<последовательность шестнадцатеричных цифр>.

Строки – последовательность букв, цифр, знаков и пробелов заключенных между символами “” или ‘’, пробелы не являются значащими символами.

Операции – последовательность знаков или последовательность букв начинающихся с точки.

Разделители предназначены для отделения одних конструкций языка от других. К ним относятся символы: , ; ( )

  1.  Общая структура микропрограммы

Микропрограмма состоит из последовательности описаний микрокоманд. Описание микрокоманды состоит из описаний действий, выполняемых этой микрокомандой. Эти действия описываются в мнемонической форме (например, R1 + z => R1; C1) и соответствуют установке различных полей микрокоманды в некоторые значения. Далее по тексту термин "описание микрокоманды" может заменяться на термин "микрокоманда" - в тех местах, где это не может привести к путанице.

При этом предполагается, что поля тех микрокоманд, которые не описываются явным образом, имеют вполне определенные значения, называемые значениями по умолчанию. Кроме того, если явное описание действий, выполняемых в микрокоманде, не затрагивает каких-либо полей микрокоманды, то эти поля сохраняют значения по умолчанию. Иными словами, можно считать, что есть некоторое содержимое микропамяти, используемое по умолчанию, а описание, выполняемое на языке микропрограммирования, изменяет отдельные его части.

Последовательно идущие описания микрокоманд (без активных меток - см. ниже) определяют содержимое микропамяти по последовательным адресам. Микропамять может состоять из 4096 микрокоманд. При этом первое описание микрокоманды соответствует микрокоманде по адресу 0, а последняя микрокоманда адресу FFF.

  1.  Метки

Описания микрокоманд могут снабжаться метками. Метки могут быть пассивными или активными.

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

M(<строка>);

где <строка> (здесь и далее) представляет собой набор символов, первый из которых не является одним из следующих - '*', '$', '#', - и ограниченный кавычками или апострофами.

Активные метки не просто помечают очередную микрокоманду, но указывают явным образом адрес микропамяти, по которому следует разместить очередную микрокоманду. В свою очередь, очередная не помеченная активной меткой микрокоманда продолжит прерванную последовательность размещаемых микрокоманд.

Активные метки также бывают двух видов: адресная и мнемоническая. Активная адресная метка имеет следующий вид:

M(<адресная строка>);

где <адресная строка> (здесь и далее) представляет собой набор символов, начинающийся с '*' и продолжающийся последовательностью шестнадцатеричных цифр. Именно эта последовательность цифр и определяет адрес микропамяти.

Мнемоническая метка имеет вид

M(<мнемоническая строка>);

где <мнемоническая строка> (здесь и далее) представляет собой набор символов, начинающийся с '$' или '#', и одной из предопределенных последовательностей символов. Каждой мнемонической строке соответствует свой адрес микропамяти. Иными словами, вместо любой мнемонической метки может быть использована соответствующая адресная метка. Фактически мнемоническая метка - это константа, которая на этапе препроцессирования заменяется на адрес. Например, M(“#ldioe”); эквивалентно M(“*f25”);.

Список предопределенных адресов

мнемоника

адрес

мнемоника

адрес

мнемоника

адрес

мнемоника

адрес

$sxtb

$E02

$push5

$E55

$ldbl8

$EA0

$downi

$EEB

$sxth

$E03

$push6

$E56

$ldbl16

$EA1

$upi

$EEC

$move

$E04

$push7

$E57

$ldbg8

$EA2

$bs

$EED

$move8

$E05

$push8

$E58

$ldbg16

$EA3

$loopp1

$EEE

$move16

$E06

$push9

$E59

$ldbg32

$EA4

$loopm1

$EEF

$zxtb

$E0A

$push10

$E5A

$ldbs

$EA5

$choice

$EFD

$zxth

$E0B

$push11

$E5B

$ldbs8

$EA6

$init

$EFE

$ext

$E0C

$push12

$E5C

$ldbs16

$EA7

$k16

$EFF

$extu

$E0D

$push13

$E5D

$stbl8

$EA8

#ldctx

#F00

$ins

$E0E

$push14

$E5E

$stbl16

$EA9

#stctx

#F01

$rins

$E0F

$alloci

$E5F

$stbg8

$EAA

#rsubi

#F02

$add

$E10

$drop1

$E60

$stbg16

$EAB

#ldim

#F03

$mul

$E11

$pop1

$E61

$stbg32

$EAC

#stim

#F04

$sub

$E12

$pop2

$E62

$stbs

$EAD

#ldir

#F05

$rsub

$E13

$pop3

$E63

$stbs8

$EAE

#stir

#F06

$addi

$E14

$pop4

$E64

$stbs16

$EAF

#ldem

#F07

$muli

$E15

$pop5

$E65

$and

$EB0

#stem

#F08

$subi

$E16

$pop6

$E66

$or

$EB1

#lder

#F09

$callr

$E17

$pop7

$E67

$xor

$EB2

#ster

#F0A

$calli

$E18

$pop8

$E68

$not

$EB3

#div

#F10

$calls

$E19

$pop9

$E69

$shr

$EB4

#divu

#F11

$ret

$E1A

$pop10

$E6A

$shl

$EB5

#mod

#F12

$retl

$E1B

$pop11

$E6B

$ashr

$EB6

#modu

#F13

$rets

$E1C

$pop12

$E6C

$eq

$EB7

#rdiv

#F14

$retls

$E1D

$pop13

$E6D

$inc

$EB8

#rdivu

#F15

$loopp

$E1E

$pop14

$E6E

$dec

$EB9

#rmod

#F16

$loopm

$E1F

$pop15

$E6F

$abs

$EBA

#rmodu

#F17

$blt

$E20

$l0

$E70

$neg

$EBB

#divi

#F18

$bltu

$E21

$l1

$E71

$shri

$EBC

#divui

#F19

$ble

$E22

$libp

$E72

$shli

$EBD

#modi

#F1A

$bleu

$E23

$libm

$E73

$ashri

$EBE

#modui

#F1B

$bgt

$E24

$lihp

$E74

$ne

$EBF

#rdivi

#F1C

$bgtu

$E25

$lihm

$E75

$nop

$EC0

#rdivui

#F1D

$bge

$E26

$li

$E76

$swap1

$EC1

#rmodi

#F1E

$bgeu

$E27

$b8

$E77

$swap2

$EC2

#rmodui

#F1F

$blti

$E28

$b80

$E78

$swap3

$EC3

#loopp16

#F20

$bltui

$E29

$b81

$E79

$swap4

$EC4

#loopm16

#F21

$blei

$E2A

$b16

$E7A

$swap5

$EC5

$bleui

$E2B

$b160

$E7B

$swap6

$EC6

$bgti

$E2C

$b161

$E7C

$swap7

$EC7

$bgtui

$E2D

$b32

$E7D

$swap8

$EC8

$bgei

$E2E

$b320

$E7E

$swap9

$EC9

$bgeui

$E2F

$b321

$E7F

$swap10

$ECA

$ls0

$E30

$ldl8

$E80

$swap11

$ECB

$ls1

$E31

$ldl16

$E81

$swap12

$ECC

$ls2

$E32

$ldg8

$E82

$swap13

$ECD

$ls3

$E33

$ldg16

$E83

$swap14

$ECE

$ls4

$E34

$ldg32

$E84

$swap15

$ECF

$ls5

$E35

$lds

$E85

$fal8

$ED0

$ls6

$E36

$lds8

$E86

$fal16

$ED1

$ls7

$E37

$lds16

$E87

$fag8

$ED2

$beq

$E38

$stl8

$E88

$fag16

$ED3

$bne

$E39

$stl16

$E89

$fag32

$ED4

$beqi

$E3A

$stg8

$E8A

$far8

$ED5

$bnei

$E3B

$stg16

$E8B

$far16

$ED6

$bgt0

$E3C

$stg32

$E8C

$rsts

$ED7

$blt0

$E3D

$sts

$E8D

$rsts8

$ED8

$bge0

$E3E

$sts8

$E8E

$rsts16

$ED9

$ble0

$E3F

$sts16

$E8F

$rsths

$EDA

$lt

$E40

$ldhl8

$E90

$rsths8

$EDB

$ltu

$E41

$ldhl16

$E91

$rsths16

$EDC

$le

$E42

$ldhg8

$E92

$rstbs

$EDD

$leu

$E43

$ldhg16

$E93

$rstbs8

$EDE

$gt

$E44

$ldhg32

$E94

$rstbs16

$EDF

$gtu

$E45

$ldhs

$E95

$ldx

$EE0

$lti

$E48

$ldhs8

$E96

$setl

$EE1

$ltu

$E49

$ldhs16

$E97

$setg

$EE2

$lei

$E4A

$sthl8

$E98

$setx

$EE3

$leu

$E4B

$sthl16

$E99

$addx8

$EE4

$gtui

$E4D

$sthg8

$E9A

$addx16

$EE5

$push0

$E50

$sthg16

$E9B

$subx8

$EE6

$push1

$E51

$sthg32

$E9C

$subx16

$EE7

$push2

$E52

$sths

$E9D

$eqi

$EE8

$push3

$E53

$sths8

$E9E

$nei

$EE9

$push4

$E54

$sths16

$E9F

$dropi

$EEA

  1.  Оформление файлов описания микропамяти

Описание микропамяти можно разбить на несколько файлов. Для этого используется директива

.Include <строка>;

которая подставляет на свое место примитивы из файла с именем <имя файла>.m68, если .m68 не указано и просто <имя файла> если файл уже имеет суффикс.

Следует обратить внимание на то, что все символы независимы от регистра, как бы ни было написано имя файла, при открытии оно преобразуется к нижнему регистру.

  1.  Символические константы

 Для описания символических констант используют выражение:

.int <идентификатор> := <константное выражение>;

В текущей версии языка можно использовать в качестве константного выражения только арифметические выражения от констант (в частности и символических) со знаками + - *

  1.  Циклы

 Для описания последовательности однотипных команд можно использовать циклы.

.for <идентификатор> [.from <константное выражение1>] [.by <константное выражение2>]  [.to <константное выражение3>] .do <тело цикла> .od

идентификатор пробегает все значения от <константное выражение1> до <константное выражение3> с шагом <константное выражение2>.

Выражения в квадратных скобках необязательны. При их отсутствии принимаются следующие значения .from 1 .by 1 .to 4096.

  1.  Операции, составляющие описание микрокоманды

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

Пример:

RonR1 + 1 =>.a2 RonR2; e;

В приведенном примере описание микрокоманды состоит из двух описаний операций.

Первое описание (RonR1 + 1 => .a2 RonR2;) представляет сложную операцию, состоящую из следующих простых операций:

  •  Выгрузка на шину DA содержимого регистра RonR1;
  •  Выгрузка на шину DB значения 1;
  •  Выполнение в АЛУ операции сложения;
  •  Выгрузка результата операции АЛУ на шину DA во втором полутакте;
  •  Сохранение содержимого шины DA в регистре RonR2.

Второе описание (e;) представляет операцию БМУ (переход на следующую микрокоманду).

В ЯМП не предусмотрено никаких специальных разделителей для отделения описаний различных микрокоманд. Вместо этого признаком конца описания считается любой примитив, представляющий операцию БМУ.

Пример:

RonR1 + 1 =>.a2 RonR2; e;

RonR2 + 1 =>.a2 RonR1; e;

  1.  Команды узлов процессора

  1.  Команды БМУ

Jz - переход на нулевой адрес, сброс стека микровызовов

Cjs - условный вызов микроподпрограммы

Jmp - безусловный переход

Cjp - условный переход

Push - загрузка счетчика циклов

Jsrp - аналогично Jrp, но вызов подпрограммы

Cjv - условный переход (аналогично Cjp)

Jrp - условный переход при выполнении условия по адресу, иначе по счетчику

Rfst - цикл с возвратом на push

Rpct - цикл с возвратом на метку по счетчику

Crtn - условный возврат из микроподпрограммы

Cjpp - условный переход

Ldct - загрузка счетчика циклов

Loop - условный выход из цикла

Cont - переход на следующую микрокоманду (примитив e;)

Twb - ветвление на три направления. При выполнении условия только уменьшает счетчик, если он не равен нулю. При невыполнении условия зависит от счетчика. Если счетчик равен нулю, - переход по адресу и очистка слова стека БМУ, иначе – переход по стеку БМУ.

  1.  Команды коммутатора адреса микрокоманды

C4 – выдача 4-битной константы на шину DB

C16 – выдача 16-битной константы на шину DB

AMK – формирование адреса микрокоманды

AMP – формирование адреса микрокоманды с разрешением прерывания

Адрес микрокоманды может быть сформирован из трех источников – микрокоманда (A), конвейер (T), шина DB (D); причем разные тетрады адреса могут быть взяты из разных источников. Возможны следующие комбинации (первая буква соответствует старшей тетраде):

AAA

AAT

ATA

ATT

AAD

ADA

DDD

Bdc – разрешение выборки байта конвейера (конвейерный строб)

  1.  Команды АЛУ

+  - сложение

-  - вычитание

and  - логическое умножение

or  - логическое сложение

xor  - исключающее или

and not  - логическое умножение с предварительной инверсией второго аргумента

or not  - логическое сложение с предварительной инверсией второго аргумента

xor not  - исключающее или с предварительной инверсией второго аргумента

.up  - нециклический сдвиг результата операции на 1 разряд влево

.down  - нециклический сдвиг результата операции на 1 разряд вправо

alu le  - сравнение на <=

alu nl  - сравнение на >=

alu eq  - сравнение на =

alu ne  - сравнение на не =

alu div  - шаг деления

alu oml  - шаг умножения

c0  - установка в ноль операнда C для сложения и вычитания

c1  - установка в единицу операнда C для сложения и вычитания

Операции сложения и вычитания выполняются следующим образом:

A + B + C - для сложения

A - B - 1 + C - для вычитания, где

A - 32-битное значение, подаваемое на вход A с шины Da

B - 32-битное значение, подаваемое на вход B с шины Db

C - 1-битное значение, подаваемое на вход C из микрокоманды

Компилятор ЯМП по умолчанию устанавливает бит микрокоманды, подающийся на вход C АЛУ в 0 для сложения и в 1 для вычитания. Таким образом, операции сложения и вычитания имеют традиционный смысл. При этом можно явным образом установить этот бит в нужное значение в описании микрокоманды (примитив C0/C1). Этим можно превратить сложение (A+B) в сложение с инкрементом (A+B+1), а вычитание (A-B) - в вычитание с декрементом (A-B-1).

  1.  Команды сдвигателя

.shl - сдвиг влево на Sd_n разрядов

.cshl - циклический сдвиг влево

.oml - шаг умножения

.div - шаг деления

  1.  Команды УКС

I(Up)  - инкремент TopI

I(Down) - декремент TopI

I(Bup)  - инкремент BotI

I(Bdown) - декремент BotI

изменение значений указателей стека происходит после выборки регистра

Адресация стека

I(S) - вершина

I(S1) - подвершина (на 1 слово ниже вершины)

I(Sn) - надвершина (на 1 слово выше вершины)

I(Sr) - смещение от вершины берется из младшей тетрады последнего байта, считанного из конвейера

I(Bot) - адресация относительно дна стека

  1.  Команды МУС

Командами МУС являются его входные условия:

Мнемоника

Значение

0

uc

истина

1

p0c

есть обмен на магистрали (в т.ч. конвейерный)

2

shzc

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

3

s0c

нулевой разряд числа после сдвига

4

s31c

31-й разряд числа после сдвига

5

normc

норма результата сдвига (sd[29] xor sd[31] = 1 где sd[n] - разряды результата сдвига)

6

zc

результат последней операции АЛУ равен нулю

7

s31

нулевой разряд результата последней операции АЛУ равен нулю

8

f8c

стек пустой (занято <= 16 слов)

9

f32c

31-й разряд результата последней операции АЛУ равен нулю

10

f16c

15-й разряд результата последней операции АЛУ равен нулю

11

f24c

стек полный (занято >= 48 слов)

12

ovr

переполнение в АЛУ

13

da0c

нулевой разряд шины DA равен нулю

14

da7c

7-й разряд шины DA равен нулю

15

da15c

15-й разряд шины DA равен нулю

16

da31c

31-й разряд шины DA равен нулю

17

db0c

нулевой разряд шины DB равен нулю

18

db7c

7-й разряд шины DB равен нулю

19

db15c

15-й разряд шины DB равен нулю

20

РПР15

сработало прерывание таймера

21

тупик

сработал тупик

22

прер

сработало прерывание

23

итк

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

24

0

ложь

25

т0

нулевой разряд регистра mask

26

т1

1-й разряд регистра mask

27

т2

2-й разряд регистра mask

28

т3

3-й разряд регистра mask

29

т4

4-й разряд регистра mask

30

т5

5-й разряд регистра mask

31

т6

6-й разряд регистра mask

32

т7

7-й разряд регистра mask

33

zrcc

zc & т5

34

zwcc

not (zc & т4)

35

lec

результат последней операции АЛУ <= 0

36

gtc

результат последней операции АЛУ >= 0

Условия с 0 по 23 могут быть инвертированы. Для этого перед мнемоникой условия ставится циркумфлекс (^).

  1.  Команды контроллера прерываний

СбросПре – обнуление РОШ и РПР;

Prer – разрешение прерываний на время выполнения данной микрокоманды.

  1.  Команды таймера

Загрузка регистров:

Регистры загружаются со старшего полуслова шины DB во втором полутакте.

Ld1 - загрузка регистра RG1 – счетчик длинного таймера

Ld2 - загрузка регистра RG3 – коэффициент умножения длинного таймера

Ld4 - загрузка регистра RG4 – короткий таймер

В связи с особенностями архитектуры, загружаемые значения должны быть на 1 меньше расчетных значений.

Выгрузка регистров:

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

0 – RG1 – счетчик длинного таймера

1 – RG4 – короткий таймер

2 – RG5 – таймер гладкого счета (старшее полуслово)

3 – RG6 – таймер гладкого счета (младшее полуслово)

Каждый такт счетчик регистров увеличивается на единицу и, досчитав до 3-х, обнуляется.

Rst - сброс счетчика регистров в ноль

Otr - выгрузка регистра, на который указывает счетчик регистров

  1.  Команды буфера интерфейсной информации

Read  - чтение слова из ОЗУ по адресу Ba в регистр Bd;

Readio  - чтение слова из ВУ по адресу Ba в регистр Bd;

Write  - запись байта из регистра Bd в ОЗУ по адресу Ba;

Write2  - запись полуслова из регистра Bd в ОЗУ по адресу Ba;

Write4  - запись слова из регистра Bd в ОЗУ по адресу Ba;

Writeio - запись слова из регистра Bd в ВУ по адресу Ba;

Blk0  - блокировка синхросерии «Т» на низком уровне на время обмена по магистрали;

Blk1  - блокировка синхросерии «Т» на высоком уровне на время обмена по магистрали;

НУБ (или nub)  - начальная установка буфера (сброс признаков процессорного и конвейерного обмена);

DCD16  - дешифрация второго байта двухбайтовой команды

  1.  Команды анализаторов

Anal (n);

Где n – номера полутактов, в которых информация будет поступать в анализаторы.

Пример:

Anal (1);

Anal (2);

Anal (12);

  1.  Совмещенные команды

Команды выхода на программный уровень:

Ret - выход на программный уровень. Эквивалентно следующей микрокоманде:

Bdc; Amk (“*e00”); prer; cjv (1, ATT);

Cret - выход на программный уровень при выполнении условия. Синтаксис:

cret (<условие>);

Эквивалентно следующей микрокоманде:

Bdc; Amk (“*e00”); prer; cjv (<условие>, ATT);

Repret - выход на программный уровень после невыполнения условия в Cret.

Эквивалентно следующей микрокоманде:

Amk (“*e00”); prer; cjv (1, ATT);

Эти команды выполняют следующие действия:

- дешифрируют текущий байт конвейера;

- формируют адрес микропрограммы, выполняющей данную команду, и передают ей управление;

- на время своего выполнения разрешают прерывания

  1.  Операторы

Оператор «конец выражения» (точка с запятой) служит для разделения выражений друг от друга.

Оператор «внутрикристальная пересылка» (обозначается ->) служит для пересылки единицы данных между регистрами внутри одного узла процессора. Направление «стрелки» указывает направление пересылки. Такая пересылка возможна, если на данном такте:

данный узел процессора не выполняет других команд;

  •  поля микрокоманды, в которых содержится команда данному узлу, не заняты командами или данными других узлов.

Пример:

z + R1 -> R2; e;

Оператор «пересылка по шине» (обозначается =>) служит для пересылки единицы данных между регистрами внутри одного либо разных узлов процессора. Направление «стрелки» указывает направление пересылки. Такая пересылка возможна, если на данном такте:

  •  свободна шина, по которой может быть осуществлена эта пересылка;
  •  узлы процессора, участвующие в пересылке, имеют свободные входы и выходы для осуществления пересылки.

Пример:

z + R1 => R2; e;

z + R1 => Ron R2; e;

В операции пересылки по шине может отсутствовать приемник пересылки (в этом случае вместо приемника в описании микрокоманды указывается примитив «.skip»). Можно указывать либо не указывать шину и полутакт (шина будет выбрана компилятором ЯМП).

Пример:

RonR2 =>.a2 RonR1; e; - пересылка с явным указанием шины и полутакта (шина DA, 2-й полутакт)

RonR2 =>.a2 skip; e; - пересылка с явным указанием шины и полутакта, без приемника.

Также возможна пересылка по шине с одним источником и несколькими приемниками. Такая пересылка возможна, если:

  •  приемники находятся в разных узлах процессора;
  •  узлы процессора, участвующие в пересылке, имеют общую шину, свободную на данном такте.

Пример:

z + R1 => R2 => Ba; e;

Ron R1 -> Ron R2 => Ba => Sd => R1; e;

  1.  Выражения

Выражением называется конструкция из операторов, операндов и команд, описывающая действия над операндами. Выражение должно заканчиваться точкой с запятой. Микрокоманда является составным выражением и обязательно должна содержать одну команду БМУ.

Примеры:

z + R1 => R2; - выражение;

z + R1 -> R2; e; - микрокоманда;

Amk (“*e00”); Bdc; cjv(1, “ATT”); - микрокоманда.


  1.  Обеспечение надежности
    1.  Основные термины

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

Элемент системы – аппаратный блок (часть какого-либо модуля), для которого характерно индивидуальное проявление неисправности или способ ее диагностики и локализации.

Конфигурация ВК – состав ВК и состояние его отдельных модулей.

Полная конфигурация ВК включает в себя троированный исправный комплекс:

Три процессора

  •  Три входных мажоритара
  •  Три выходных мажоритара
  •  Три магистрали
  •  Три ОЗУ и ПЗУ

Максимальная конфигурация отличается от полной набором внешних устройств на магистрали.

Минимальная конфигурация включает в себя двойной исправный комплекс:

Два процессора

  •  Два входных мажоритара
  •  Два выходных мажоритара
  •  Две магистрали
  •  Два ОЗУ и ПЗУ
  •  Минимально необходимый набор внешних устройств

Сбой одного из модулей в минимальной конфигурации ведет к тупику, а отказ – к отказу ВК.

Модули ВК могут находиться в следующих основных состояниях:

Рабочее – модуль полностью выполняет свои функции без реакции схем контроля.

  •  Отказ – модуль не может выполнять свои функции вследствие необратимых процессов, произошедших в модуле. Восстановление работоспособности без ремонтных работ невозможно.
  •  Под сомнением – возникает после получения сигнала о неисправности данного модуля и сохраняется до конца выполнения процесса диагностики сбой/отказ, после чего выполняется соответствующая программа обработки.
  •  Частичная работоспособность – частично отказавшие, но выполняющие свои основные функции модули. Например, нарушение схемы контроля четности, выход из строя отдельных ячеек памяти…

Неисправная работа модулей может быть классифицирована как:

Сбой – несистематические нарушения в работе модуля или его элементов, не связанные с технической неисправностью.

  •  Отказ – систематически неправильное функционирование модуля, связанное с технической неисправностью.

При работе ВК реакцией на расхождение результатов какой-либо операции является установление соответствующих разрядов регистра ошибок и инициирование обработки прерывания. Различают два типа расхождения результатов:

Ошибка – это такое появление сигнала неисправности, когда схемы мажорирования информации обеспечивают автоматическое исправление последствий ошибки (например, ошибся один из трех процессоров).

  •  Тупик – это ситуация, когда дальнейшее продолжение работы с данными результатами невозможно (например, двойная ошибка процессоров, или ошибка одного из процессоров в неполной конфигурации).

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

САС – Супервизор аварийных ситуаций – совокупность аппаратных, микропрограммных и программных компонентов вычислительного комплекса, отвечающих за повышение надежности его работы.

  1.  Аппаратные методы

Аппаратные компоненты САС включают в себя:

Схемы контроля (входные и выходные мажоритары).

  •  Программно недоступные регистры управления конфигурацией (МОН).
  •  Программно доступные 16-разрядные регистры ошибок и прерываний и их маски (РОШ, РПР, МРОШ, МРПР).
  •  Программно недоступные регистры управления тупиками.

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

Возможны три ситуации:

Все три процессора подали на вход одинаковое значение – в этом случае значение пишется в память.

  •  Один из процессоров ошибся – в память пишется значение с двух других процессоров, в регистрах РОШ всех процессоров выставляется соответствующий бит. Это делается для того, чтобы по завершении цикла обмена выровнять процессор на микропрограммном уровне.  
  •  Все три процессора подают на вход разные значения – тупик, происходит немедленное прерывание (без завершения цикла обмена), происходит сброс процессоров.

В случае чтения из памяти аналогично функционирует входной мажоритар.

В минимальной конфигурации ошибки одного процессора или памяти достаточно для возникновения тупика.

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

Программно недоступные регистры управления конфигурацией (МОН) – находятся в блоке арбитра. Значение, записанное в МОН (на микропрограммном уровне) влияет на то, с какими магистралями будет вестись работа. Это значение может быть побитовым ИЛИ следующих трех значений:

1 – первая магистраль

  •  2 – вторая магистраль
  •  4 – третья магистраль

Кроме того, в блоке арбитра хранится номер процессора, что дает возможность “развести” процессоры для тестирования схем контроля.

Программно доступные 16-разрядные регистры ошибок и прерываний и их маски (РОШ, РПР, МРОШ, МРПР) – регистры, находящиеся в схеме контроллера прерываний. Биты в регистрах РОШ и РПР выставляются аппаратно мажоритарами, таймером и внешними устройствами. Если выставленный бит не замаскирован, и разрешено прерывание, то в коммутаторе микроадреса генерируется адрес FFF, по которому находится микропрограмма обработки прерываний.

Значение битов в регистре РОШ:

ошибка процессора 1

  1.  ошибка процессора 2
  2.  ошибка процессора 3
  3.  ошибка магистрали 1
  4.  ошибка магистрали 2
  5.  ошибка магистрали 3
  6.  зависание в канале  1
  7.  зависание в канале  2
  8.  зависание в канале  3
  9.  ошибка четности в канале 1
  10.  ошибка четности в канале 2
  11.  ошибка четности в канале 3
  12.  флаг пошагового режима
  13.  флаг режима выравнивания
  14.  0
  15.  зависание процессора

Значение битов в регистре РПР

прерывание от внешнего устройства

  1.  прерывание от внешнего устройства
  2.  прерывание от внешнего устройства
  3.  прерывание от внешнего устройства
  4.  прерывание от внешнего устройства
  5.  прерывание от внешнего устройства
  6.  прерывание от внешнего устройства
  7.  прерывание от внешнего устройства
  8.  прерывание от внешнего устройства
  9.  прерывание от внешнего устройства
  10.  прерывание от внешнего устройства
  11.  прерывание от внешнего устройства
  12.  запрос на обмен от ТА
  13.  обмен с ТА завершен
  14.  запрос на прерывание от микропрограммной части САС
  15.  прерывание от интервального таймера

Следует отметить, что регистр ошибок и его маска не входят в контекст задач RTEMS и являются общими для всех приложений, в то время как РПР и МРПР загружаются для каждой задачи вместе с ее контекстом.

Программно недоступные регистры управления тупиками (RG16, RG10) – регистры, находящиеся в схеме контроллера прерываний. Биты в регистрах RG16 и RG10 соответствуют условиям возникновения тупика. Тупик по регистру RG16 возникает в случае если выставлен соответствующий разряд РОШ.

Значение битов в регистре RG10:

0 – ошибка 2-х процессоров из 3-х

1 – ошибка сравнения 2-х магистралей из 3-х

2 – зависание 2-х магистралей из 3-х

3 – ошибка  четности 2-х магистралей из 3-х

4 – резерв

5 – ошибка 3-х процессоров

6 – ошибка сравнения 3-х магистралей

7 – зависание 3-х магистралей

8 – ошибка  четности 3-х магистралей

9 – резерв

  1.  Микропрограммные методы

К микропрограммным компонентам САС относятся:

Процедура начальной загрузки

  •  Микропрограмма обработки прерываний
  •  Специальные команды из системы команд

Процедура начальной загрузки

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

Процедура начальной загрузки начинает свою работу как результат наступления одного из следующих событий:

включение питания ВК

  •  включение в систему исправленного процессора вместо забракованного (только в этом процессоре)
  •  тупик

Действия, выполняемые процедурой начальной загрузки, зависят от того события, которое ее вызвало, а также от следующих факторов:

режим работы СВК (штатный или отладочный)

  •  источник исполняемого кода (диск, ПЗУ, отладчик) - имеет смысл только для отладочного режима работы СВК
  •  конфигурация СВК

Можно выделить следующие наиболее принципиальные требования, предъявляемые к процедуре начальной загрузки:

способность самостоятельно отслеживать (по мере возможности) те вышеперечисленные факторы, которые влияют на ее действия - иными словами необходимость в создании специальных версий микропамяти для различных ситуаций должна, насколько это возможно, минимизироваться

  •  отслеживание и диагностика аварийных ситуаций, возникающих в ходе ее работы

Микрозагрузчик – микропрограммная компонента, обеспечивающая старт СВК в отладочном режиме. Комплекс входит в режим микрозагрузчика после процедуры начальной загрузки. В этом режиме процессоры работают в цикле, постоянно проверяя слово памяти по адресу 0х400. В это время инструментальный ПК может записать в это слово команды микрозагрузчика:

80 – NOP – пустая операция.

81 – Start – запуск с адреса, лежащего по адресу 0.

82 – Continue – запуск с адреса, лежащего по адресу caPсLo (0x41c).

83 – ResetRegs – установка регистров в начальное состояние.

84 – Sync – Синхронизация каналов. Производится выравнивание ОЗУ по 2-й грани. Начальный адрес и длина области ОЗУ для выравнивания находятся соответственно по адресам caAddrLo (0x404) и caLengthLo (0x408).

85 – Step – режим пошагового исполнения. Производится запуск с адреса, лежащего в ячейке caPcLo (0x41c), при этом в РОШ и МРОШ выставляется флаг пошагового режима.

8A – переход в режим тестирования ОЗУ. В регистр RonRamTest заносится соответствующий флаг, после чего микрозагрузчик попадает в короткий цикл с разрешенным прерыванием. Прерывание инициирует инструментальный ПК (прерывание от ТА), он же и проводит тестирование ОЗУ.  

Выполнив команду, микрозагрузчик записывает в память (по адресу 0x400) результат:

01 – Команда выполнена.

02 – Останов по break.

03 – Останов по Step.

0F – Ошибка.

Загрузка программы в память в отладочном режиме осуществляется через технологический адаптер с инструментального ПК.

Микропрограмма обработки прерываний

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

Процедура обработки прерываний начинает свою работу как результат одновременного наступления следующих событий:

разрешение процессора на прерывание

  •  ненулевое значение следующего выражения: (МРОШ .and РОШ) .or (МРПР .and РПР) где РОШ - регистр ошибок, РПР - регистр прерываний, МРОШ - маска регистра ошибок, МРПР - маска регистра прерываний

Разрешение процессора на прерывание представляет собой бит микрокоманды, в которой разрешено прерывание. Такие биты установлены в последних микрокомандах микропрограмм, реализующих машинные инструкции, а также в некоторых других местах, где уход на процедуру обработки прерываний необходим и безопасен.

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

Прерывание от таймера

Прерыванию от таймера соответствует 15-й бит РПР. Номер вектора для микропрограммного прерывания: 5.

Микропрограммная обработка прерывания от таймера заключается в следующем:

проверка источника прерывания

  •  проверка корректности прерывания
  •  переустановка таймера на следующий интервал
  •  снятие прерывания от таймера
  •  переход на программный обработчик

Проверка источника прерывания заключается в проверке разрядов РПР, соответствующих ТА, т.к. номера векторов прерываний ТА и таймера совпадают.

Проверка корректности прерывания от таймера заключается в попытке обнулить значение соответствующего бита РПР. В случае реального прерывания от таймера такая попытка должна закончиться неудачей. Если же обнуление регистра РПР удалось, то обработка прерывания на этом заканчивается (с уведомлением САС о случившемся).

Прерывания от устройств

Прерываниям от устройств соответствуют биты РПР в диапазоне 0-11. Номер вектора для микропрограммного прерывания: 4. Микропрограммная обработка прерывания заключается в переходе на программный обработчик.

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

Технологические прерывания

Технологическим прерываниям соответствуют 12-й и 13-й биты РПР. Вектор для  микропрограммного технологического прерывания: 5. Возникновение такого прерывания отслеживается с помощью непосредственного анализа РПР и МРПР до ветвления по вектору (таким образом технологические прерывания получают самый высокий приоритет в системе).

12-й бит РПР означает вход в режим обмена данными с технологическим адаптером. При этом выполняются следующие действия:

останавливается конвейер

  •  открывается прямой доступ к памяти
  •  в регистр обмена ТА заносится признак начала обмена
  •  запоминаются текущие значения МРПР и МРОШ
  •  МРОШ обнуляется, в МРПР заносится значение 0x2000
  •  инициируется "бесконечный" цикл с разрешением прерывания (ожидание 13-го бита РПР)

13-й бит РПР означает выход из режим обмена данными с технологическим адаптером. При этом выполняются следующие действия:

в регистр обмена ТА заносится признак окончания обмена

  •  закрывается прямой доступ к памяти
  •  запускается конвейер
  •  восстанавливаются значения МРПР и МРОШ

Аппаратные ошибки – ошибки, фиксируемые мажоритарами.

Ошибки процессора

Ошибкам процессора соответствуют биты РОШ в диапазоне 0-2. Номер вектора для микропрограммного прерывания по ошибке процессора: 10.

Микропрограммная обработка ошибок процессора заключается в следующем:

обновление счетчиков ошибок

  •  анализ возникшей ошибки на сбой/отказ
  •  выведение из конфигурации ошибившегося процессора
  •  отображение в рабочей области информации о последней ошибке
  •  попытка выравнивания ошибившегося процессора
  •  обнуление разряда РОШ, соответствующего ошибившемуся процессору

Выведение из конфигурации ошибившегося процессора осуществляется путем сопоставления значений РОШ и регистра арбитра (ARB), в котором доступен номер процессора. Выведенный из конфигурации ошибившийся процессор попадает в бесконечный цикл с разрешенным прерыванием, предварительно установив значение $2000 в МРОШ (ожидание выравнивающего прерывания). Попытка выравнивания ошибившегося процессора осуществляется путем записи значения $2000 в МРОШ с последующим разрешением прерывания.

В микропрограммном обработчике прерываний предусмотрена специальная ветка для выравнивающего прерывания.

Ошибки магистралей

Ошибкам магистралей соответствуют биты РОШ в диапазоне 3-11. Номер вектора для микропрограммного прерывания по ошибке магистрали: 12.

Микропрограммная обработка ошибок магистралей состоит в следующем:

обновление счетчиков ошибок

  •  анализ возникшей ошибки на сбой/отказ
  •  отображение в рабочей области информации о последней ошибке
  •  обнуление разрядов РОШ, соответствующих ошибкам магистралей.

При этом на программный уровень возлагается:

выведение магистрали из конфигурации

  •  ввод магистрали в конфигурацию
  •  выравнивание содержимого памяти

Ошибки устройств на отдельных магистралях

Анализ ошибок устройств на отдельных магистралях производится внутри команд обращения к таким устройствам. Проверке подвергаются биты РОШ в диапазоне 6-11. Анализ состоит в сравнении значений РОШ (в вышеуказанных битах) до и после обмена.

Микропрограммная обработка ошибок устройств на отдельных магистралях состоит в активизации прерывания на программном уровне.

Специальные команды из системы команд

В системе команд процессора есть специальная диагностическая команда diag (код FF 41), действия которой определяются следующим за ней в коде байтом. Эта команда снимает со стека две позиции и возвращает одну. Возможные подкоманды команды diag таковы:

00 – ввод процессора в конфигурацию

  •  03 – тестирование мажоритаров
  •  07 – выравнивание регистров

Команда ввода процессора в конфигурацию подается после замены отказавшего процессора, когда комплекс работает в неполной конфигурации. Эта команда записывает в РОШ специальное выравнивающее прерывание, при обработке которого регистры всех трех процессоров выравниваются, и снимается маска с ошибок вновь введенного процессора.

Команда выравнивания регистров выравнивает регистры всех процессоров, присутствующих в конфигурации. В случае неудачи, отказавший процессор автоматически выводится из конфигурации.

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

Код

Мнемоника

Опе-ранды

Описание

FF 70

sasloadmon

–> s

Загрузка MON на вершину стека

FF 71

sasmemdown

s –>

Вывод грани ОЗУ из конфигурации. На стеке номер грани начиная с 0

FF 72

sasmemup

s –> s

Ввод грани ОЗУ в конфигурацию. На стеке номер грани начиная с 0. Возвращает 0 в случае успеха, иначе 1

FF 73

sasgetcnt

s –> s

Загрузка счетчика ошибок на вершину стека. На стеке номер счетчика (совпадает с номером разряда РОШ)

FF 74

saszcnt

s –>

Обнуление счетчика ошибок. На стеке номер счетчика (совпадает с номером разряда РОШ)

FF 75

sasmemsync

ss –>

Выравнивание граней ОЗУ по второй грани. На вершине стека длина в словах, под вершиной начальный адрес

Тестирование мажоритаров  

Команда тестирования мажоритаров должна вызываться только в полной конфигурации, иначе она провоцирует тупик.  

Процедура тестирования входных мажоритаров на отлов ошибки в битах данных:

  •  запись «0» во все 3 ОЗУ;
  •  запись «1» в 1 ОЗУ;
  •  чтение записанного значения из трех ОЗУ;
  •  если в РОШ не установился флаг ошибки – то отказ мажоритара.

Данная процедура повторяется для каждого бита данных и для каждого входного мажоритара.

Процедура тестирования выходных мажоритаров на отлов ошибки в битах данных:

  •  записать в буферы данных всех процессоров некоторое значение;
  •  записать в буфер данных одного процессора другое значение;
  •  произвести запись в ОЗУ;

если в РОШ не установился флаг ошибки – то отказ мажоритара.

Данная процедура повторяется для каждого бита данных и для каждого выходного мажоритара.

Кроме тестирования отлова ошибок в битах данных, производится тестирование на предмет генерации отдельными мажоритарами ложных ошибок. Для этого производятся записи и чтения через один тестируемый канал.

Результатом команды тестирования мажоритаров является выгруженное на стек слово, значение битов которого:

01 отказ выходного мажоритара 1

02 отказ выходного мажоритара 2

03 отказ выходного мажоритара 3

04 отказ входного мажоритара 1

05 отказ входного мажоритара 2

06 отказ входного мажоритара 3

  1.  Программные методы

Программная структура САС – это набор следующих взаимодействующих задач в среде RTEMS:

SASInit – инициализирующая задача

  1.  SAS_Manager – управляющий процесс
  2.  Задачи фоновой диагностики:
    1.  RAM_testing – задача тестирования оперативной памяти
    2.  CPU_testing – задача тестирования процессоров и схем контроля
      1.  

Инициализирующая задача

Запуск управляющего процесса и задач фоновой диагностики происходит из инициализирующей задачи САС. Эта задача выполняется при старте RTEMS среди других пользовательских инициализирующих задач, так как входит в соответствующую конфигурационную таблицу RTEMS.

Инициализирующая задача САС выполняет следующие действия:

Создает и запускает управляющий процесс.

  •  Создает и запускает задачи фоновой диагностики.
  •  Создает очередь управления САС.
  •  Создает очередь статуса САС.

После выполнения этих действий инициализирующая задача удаляет себя из системы.

Управляющий процесс

Управляющий процесс запускается из инициализирующей задачи САС. Посредством двух очередей (очереди контроля и очереди статуса) он осуществляет диалог с СПО. Команды СПО посылаются в очередь контроля САС, а результаты их выполнения – в очередь статуса. Кроме того, очередь статуса используется другими компонентами САС для посылки сообщений об ошибках.

Перечень возможных команд СПО:

Запрос текущей конфигурации

  •  Запрос на введение процессора в конфигурацию
  •  Запрос на введение магистрали в конфигурацию
  •  Запрос на выведение процессора из конфигурации
  •  Запрос на выведение магистрали из конфигурации

Выполнив команду оператора, управляющий процесс посылает ответ в очередь статуса. Строгий формат очередей САС и оператора будет приведен ниже.

Процедуры, используемые управляющим процессом для реализации его задач

Для выполнения команд СПО управляющий процесс располагает следующими процедурами:

Получение текущей конфигурации

  •  Вывод процессора из конфигурации
  •  Ввод процессора в конфигурацию
  •  Вывод магистрали из конфигурации
  •  Ввод магистрали в конфигурацию
  •  Сведение граней

Первая процедура заключается в анализе маски регистра ошибок и значений МОНов. Этот анализ позволяет узнать:

Какие процессоры присутствуют в конфигурации

  •  Какие магистрали присутствуют в конфигурации

Вывод процессора из конфигурации заключается в маскировании ошибок этого процессора.

Ввод процессора в конфигурацию осуществляется с помощью специальной команды, производящей его синхронизацию с работающими процессорами.

Процедура вывода магистрали из конфигурации заключается в маскировании ошибок данной магистрали и запрещении работы с магистралью через регистры МОН.

Последовательность ввода магистрали в конфигурацию:

  •  разрешение работы с магистралью через МОН;
  •  сведение граней;
  •  снятие маски ошибок данной магистрали.

Задача процедуры сведения граней заключается в быстром введении нового ОЗУ в рабочее состояние.

Задача фонового тестирования оперативной памяти

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

Задача фонового тестирования процессоров и схем контроля

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

Перед каждым тестом выполняются команды фонового выравнивания регистров процессоров и тестирования мажоритаров.

Формат очередей

Взаимодействие САС с СПО осуществляется с помощью двух очередей сообщений – очереди контроля (входная очередь САС) и очереди статуса (выходная очередь САС).

Сообщение в обеих очередях имеет следующий вид:

/* SAS message format */

struct SAS_message {

/* current configuration */

unsigned int config;

/* Command number */

unsigned short number;

/* Type of the message */

unsigned char type;

 

/* Error code (CPU, MAG, MAJ) */

unsigned char err;

 

/* SPO request */

unsigned char request;

/* Number of the device */

unsigned char channel;

  1.  

/* Number of test failed */

unsigned char test;

/* reserved */

unsigned char reserved[5];

};

config – текущая конфигурация, посылается в очередь статуса САС в ответ на запрос конфигурации, или на запрос об изменении конфигурации. Младшие три бита слова соответствуют трем процессорам, следующие три – трем магистралям. Единица в любом из битов означает присутствие соответствующего устройства в конфигурации, а 0 – его отсутствие.

number – номер команды. Присутствует в каждой команде СПО и в ответе на нее. Служит для синхронизации команд и ответов.

type – тип сообщения. Разделяет ответы на команды и сообщения об ошибках в очереди статуса САС. Допустимы следующие два значения:

/* The command result */

#define RESULT_MSG   0

/* Error message */

#define ERR_MSG    1

err – код ошибки. В сообщении об ошибке содержит характер неисправности. Возможны следующие значения:

/* Otkaz CPU */

#define CPU_OUT_OF_ORDER   1

/* Sboi CPU */

#define CPU_MALFUNC    2

/* Otkaz OZU */

#define RAM_OUT_OF_ORDER   3

/* Sboi OZU */

#define RAM_MALFUNC    4

/* Otkaz KOZU */

#define CRAM_OUT_OF_ORDER   5

/* Otkaz VU */

#define EXT_DEVICE_OUT_OF_ORDER  6

/* Otkaz MAJ */

#define IN_MAJ_OUT_OF_ORDER  7

#define OUT_MAJ_OUT_OF_ORDER  8

/* CPU command test failed */

#define CPU_COMMAND_FAIL   9

request – команда СПО. Возможны следующие значения:

/* current configuration request */

#define CONFIG_REQUEST   0

/* insert cpu in configuration */

#define INSERT_CPU    1

/* remove cpu from configuration */

#define REMOVE_CPU   2

/* insert magistral in configuration */

#define INSERT_MAG   3

/* remove magistral from configuration */

#define REMOVE_MAG    4

channel – номер троированного устройства. Присутствует в командах изменения конфигурации и в сообщениях о неисправностях.

#define CHANNEL_1    1

#define CHANNEL_2    2

#define CHANNEL_3    3

test – номер командного теста, не прошедшего сравнение с результатом. Может быть от 1 до 248 (по количеству командных тестов).

reserved – неиспользуемые байты.

  1.  Динамика работы

В этой главе описана динамика процесса реакции САС на аппаратные ошибки, включая реакцию аппаратных, микропрограммных и программных компонент.

  1.  Тупик

В случае возникновения тупика происходит аппаратное переключение на микропрограмму начального старта.

  1.  Аппаратная реакция на ошибки

Аппаратная реакция для всех ошибок процессоров и магистралей одинакова: при возникновении ошибки она фиксируется в РОШ, и происходит переход на микропрограмму обработки прерываний.

  1.  Ошибка процессора

Дальнейшая микропрограммная обработка ошибки процессора происходит следующим образом:

  •  маскирование ошибки процессора;
  •  попытка выравнивания процессоров;
  •  проверка на сбой/отказ и останов процессора в случае отказа;
  •  снятие маски ошибок процессора;
  •  установка 14 разряда РПР.

Единица в 14-м разряде РПР вызовет специальное прерывание. Микропрограммная обработка его заключается в вызове программного обработчика. Задача программного обработчика в случае ошибки процессора заключается в посылке соответствующего сообщения в очередь статуса САС.

  1.  Ошибки ОЗУ

Микропрограммная реакция на ошибки ОЗУ происходит следующим образом:

  •  производится контрольное чтение и запись в ОЗУ;
  •  вывод отказавшего ОЗУ из конфигурации, если был отказ;
  •  обновление счетчиков ошибок;
  •  запись признака ошибки в ОЗУ;
  •  обнуление разрядов РОШ, соответствующих ошибкам магистралей;
  •  установка 14 разряда РПР.
    1.  Ошибки зависания и четности при работе с внешними устройствами

Схема обработки ошибок при работе с внешними устройствами несколько отличается от схемы обработки ошибок памяти. Дело в том, что в микропрограммном обработчике прерываний практически невозможно определить, при работе с каким устройством произошла ошибка. Поэтому было принято решение микропрограммную обработку ошибки делать прямо в команде работы с ВУ, а в микропрограмме обработки прерываний вызывать программный обработчик.


  1.  Безопасность жизнедеятельности
    1.  Анализ опасных и вредных факторов, выявленных на рабочем месте, при работе с ПЭВМ

При разработке системы была использована электронно- вычислительная машина шестого поколения на базе процессора «Intel Pentium IV». Основная конфигурация:

Компонент:

Модель (описание).

Материнская плата

ASUS P5GD1 PRO на чипсете Intel 915P.

Процессор

Intel Pentium 4 3000 MHz.

Оперативная память

2048 Mb

Видеокарта

Gigabyte nVidia GeForce 6600 GT 128 Mb.

Жесткий диск

120 Gb Seagate Barracuda , SATA.

Звуковая карта

Realtek HD Audio ALC861 8-Chanel audio CODEC (on-board)

DVD±R/RW – DL Recorder

NEC ND-3520A

Клавиатура

Microsoft Natural Multimedia Keyboard

Манипулятор мышь

Logitech  M-BJ29 (optical)

Принтер лазерный

Brother HL-5040

Монитор 19”

LG Electronics L1930SQ

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

5.1.1 Анализ вредного воздействия ЭВМ на человека

В процессе работы с компьютером оператор подвергается вредному воздействию ряда факторов, которые классифицируются санитарно-эпидемиологическими правилами и нормативами СанПиН 2.2.2/2.4.1340-03 "Гигиенические требования к персональным электронно-вычислительным машинам и организации работы".

Повышенное значение напряжения в электрической цепи, замыкание которой может произойти через тело человека.

Высокое напряжение питания в первичной цепи (блок питания) составляет 200В с частотой 50 Гц, а катодное напряжение в мониторе достигает 20 кВ;

Высокое напряжение питания во вторичной цепи питания достигает 1000 В с частотой 50 Гц.

Повышенный уровень статического электричества. Широкое использование при изготовлении и работе ЭВМ диэлектрических и полупроводниковых материалов значительно расширило область появления статического электричества.

Повышенный уровень электромагнитного излучения. Требования выдвигаемые к оборудованию с этой точки зрения изложены в п. VII. СанПиН 2.2.2/2.4.1340-03.

Временные допустимые уровни ЭМП, создаваемых ПЭВМ на рабочих местах пользователей, а также в помещениях образовательных, дошкольных и культурно-развлекательных учреждений, представлены в таблице 5.1.

Наименование параметров

ВДУ

Напряженность электрического поля

в диапазоне частот 5 Гц - 2 кГц

25 В/м

в диапазоне частот 2 кГц - 400 кГц

2,5 В/м

Плотность магнитного потока

в диапазоне частот 5 Гц - 2 кГц

250 нТл

в диапазоне частот 2 кГц - 400 кГц

25 нТл

Напряженность электростатического поля

15 кВ/м

Таблица 5.1. Временные допустимые уровни ЭМП, создаваемых ПЭВМ на рабочих местах

  1.  Требования к визуальным параметрам ВДТ, контролируемым на рабочих местах

Предельно допустимые значения визуальных параметров ВДТ, контролируемые на рабочих местах, представлены в приложении  в таблице 2.

N

Параметры

Допустимые значения

1

Яркость белого поля

Не менее 35 кд/кв.м

2

Неравномерность яркости рабочего поля

Не более +-20%

3

Контрастность (для монохромного режима)

Не менее 3:1

4

Временная нестабильность изображения (мелькания)

Не должна фиксироваться

5

Пространственная нестабильность изображения (дрожание)

Не более 2 х 10(-4L), где L - проектное расстояние наблюдения, мм

Таблица 5.2. Визуальные параметры ВДТ, контролируемые на рабочих местах

  1.  Психофизиологические нагрузки

Физические нагрузки. При работе с ПЭВМ возникают статические нагрузки, которые влекут за собой такие болезни как остеопатия, боль в спине и шее, запястный синдром и геморрой.

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

  1.  Обеспечение безопасности рабочего места оператора при работе с ПЭВМ

Оборудование рабочего места оператора при работе с компьютером должно соответствовать СанПиН 2.2.2/2.4.1340-03, а также могут использоваться рекомендации, изложенные выше.

На основании аспектов, описанных в предыдущей главе, определяются требования по обеспечению безопасности рабочего места при работе с ПЭВМ:

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

Необходимо не допускать к компьютеру лиц, страдающих дефектами опорно-двигательного аппарата, глаз, кожи;

Видеоадаптеры и мониторы должны поддерживать большую частоту обновления изображения (не менее 75 Гц);

  1.  Общие требования к организации рабочих мест пользователей ПЭВМ

Согласно СанПиН 2.2.2/2.4.1340-03 к помещению, в котором располагаются рабочие места операторов ПЭВМ предъявляются следующие требования:

·   При размещении рабочих мест с ПЭВМ расстояние между рабочими столами с видеомониторами (в направлении тыла поверхности одного видеомонитора и экрана другого видеомонитора), должно быть не менее 2,0 м, а расстояние между боковыми поверхностями видеомониторов - не менее 1,2 м.

·  Рабочие места с ПЭВМ в помещениях с источниками вредных производственных факторов должны размещаться в изолированных кабинах с организованным воздухообменом.

·   Рабочие места с ПЭВМ при выполнении творческой работы, требующей значительного умственного напряжения или высокой концентрации внимания, рекомендуется изолировать друг от друга перегородками высотой 1,5 - 2,0 м.

·   Экран видеомонитора должен находиться от глаз пользователя на расстоянии 600 - 700 мм, но не ближе 500 мм с учетом размеров алфавитно-цифровых знаков и символов.

·  Конструкция рабочего стола должна обеспечивать оптимальное размещение на рабочей поверхности используемого оборудования с учетом его количества и конструктивных особенностей, характера выполняемой работы.

· При этом допускается использование рабочих столов различных конструкций, отвечающих современным требованиям эргономики. Поверхность рабочего стола должна иметь коэффициент отражения 0,5 - 0,7.

·  Конструкция рабочего стула (кресла) должна обеспечивать поддержание рациональной рабочей позы при работе на ПЭВМ позволять изменять позу с целью снижения статического напряжения мышц шейно-плечевой области и спины для предупреждения развития утомления. Тип рабочего стула (кресла) следует выбирать с учетом роста пользователя, характера и продолжительности работы с ПЭВМ.

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

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

  1.  Требования к организации и оборудованию рабочих мест с ПЭВМ для взрослых пользователей

·        Высота рабочей поверхности стола для взрослых пользователей должна регулироваться в пределах 680 - 800 мм; при отсутствии такой возможности высота рабочей поверхности стола должна составлять 725 мм.

·        Модульными размерами рабочей поверхности стола для ПЭВМ, на основании которых должны рассчитываться конструктивные размеры, следует считать: ширину 800, 1000, 1200 и 1400 мм, глубину 800 и 1000 мм при нерегулируемой его высоте, равной 725 мм.

·        Рабочий стол должен иметь пространство для ног высотой не менее 600 мм, шириной - не менее 500 мм, глубиной на уровне колен – не менее 450 мм и на уровне вытянутых ног - не менее 650 мм.

·        Конструкция рабочего стула должна обеспечивать:

o       Ширину и глубину поверхности сиденья не менее 400 мм;

o       Поверхность сиденья с закругленным передним краем;

o       Регулировку высоты поверхности сиденья в пределах 400 - 550 мм и углам наклона вперед до 15 град, и назад до 5 град.;

o       высоту опорной поверхности спинки 300 +-20 мм, ширину - не менее 380 мм и радиус кривизны горизонтальной плоскости - 400 мм;

o       угол наклона спинки в вертикальной плоскости в пределах +-30 градусов;

o       регулировку расстояния спинки от переднего края сиденья в пределах 260 - 400 мм;

o       стационарные или съемные подлокотники длиной не менее 250 мм и шириной - 50 - 70 мм;

o       регулировку подлокотников по высоте над сиденьем в пределах 230 +-30 мм и внутреннего расстояния между подлокотниками в пределах 350 -500 мм.

o       Рабочее место пользователя ПЭВМ следует оборудовать подставкой для ног, имеющей ширину не менее 300 мм, глубину не менее 400 мм, регулировку по высоте в пределах до 150 мм и по углу наклона опорной поверхности подставки до 20°. Поверхность подставки должна быть рифленой и иметь по переднему краю бортик высотой 10 мм.

o       Клавиатуру следует располагать на поверхности стола на расстоянии 100 - 300 мм от края, обращенного к пользователю или на специальной, регулируемой по высоте рабочей поверхности, отделенной от основной столешницы.

  1.  Искусственное освещение помещения

Для искусственного освещения в настоящее время применяются лампы накаливания и газоразрядные лампы:

            Люминесцентные

            Дуговые ртутные (ДРЛ)

            Дуговые ртутные с йодидами металлов (ДРИ)

            Ксеноновые

По конструктивному исполнению искусственное освещение помещений может быть общим (равномерным или локализованным) или комбинированным.

Общее освещение рекомендуется устраивать в помещениях, где равномерно по площади распределено оборудование и выполняются, где равномерно по площади распределено оборудование и выполняются  однородные работы.

            Комбинированное освещение применяется:

- при выполнении точных работ;

- при необходимости иметь на рабочих местах строго определённого или переменное направление света:

- если оборудование создает глубокие, резкие токи:

- если рабочие поверхности расположены вертикально.

Расчет искусственного освещения является комплексной задачей, в процессе решения которой определяют число светильников и их размещение, мощности источника света, необходимого для создания освещённости.

Проектируя осветительную установку, необходимо решить ряд вопросов.

а) Выбрать систему освещения. При этом необходимо учитывать, что экономичнее система комбинированного освещения, но в гигиеническом отношении лучше система общего освещения, так как она создаёт более равномерное распределение световой энергии по площади. Применяя локализованное общее освещение, проще добиться высоких уровней освещенности на рабочих местах без значительных энергетических затрат.

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

в) Выбрать тип светильников с учётом загрязнённости воздушной среды, требований к распределению яркостей в поле зрения и взрыва – и пожаро-безопасности.

При необходимости создание освещённости в горизонтальной плоскости наиболее целесообразны светильники прямого света (класса II), а в помещениях со светлыми потолками и стенами светильники преимущественно прямого света (класса H). В помещениях, где рабочие поверхности находятся произвольном расположении вертикальных плоскостях, применяются светильники рассеянного света (класса Р). для освещения административно-конторских помещений и лабораторий обычно используются светильники преимущественно прямого и рассеянного света.

г) Определить нормируемою освещённость на рабочем месте. Для этого необходимо установить характер выполняемой работы по наименьшему размеру объекта различения, оценить контраст объекта фоном и фон на рабочем месте и по сНиП П-4-79 в соответствии с выбранной системой освещения и типом источника света найти нормируемую освещенность Ен.

д) Определить количество светильников  и их расположение по площади освещаемого помещения. Светильники могут располагаться рядами или в шахматном порядке.

Рассчитываем общее освещение машинного зала вычислительного центра, план которого представлен на рисунке 4.1.

 

Рисунок 4.1 план вычислительного центра

Помещение имеет размеры:

А = 20м, В = 5м, Н = 4м. Высота рабочих столов = 1м.

Выбираем подвесные светильники рассеянного света (класса Р) типа ЛСП 01 с двумя люминесцентными лампами типа ЛХБ. По нормам освещенности определяем для машинного зала ВЦ Ен = 400 лк. Выбираем коэффициент запаса Кз = 1,5,hсв = 0,5.

Определяем высоту подвеса светильника:

           

            h = Hhсв – hрм = 4 – 0.5 – 1 = 2,5м.

Из характеристик светильника ЛСП 01 выбираем значение lнв = 1,6

Определяем наилучшее расстояние между соседними рядами светильников:

 

Lнв = lнв*h = 1,6*2,5 = 4м.

Рассчитываем количество рядов светильников nв:

Nв = В/Lнв = 5/4 = 1,25 два ряда.

Выбираем коэффициенты отражения потолка rп = 70%, стен rс= 50% и расчётной поверхности rрп = 10%.

Рассчитаем индекс помещения  i по формуле

i = A*B/h*(A+B) = 5*20/2.5*(5+20) = 1.6 примерно 1,5

h = 0,47

Определяем световой поток от светильников одного ряда :

Fp = Eн*S*z*kз/n*h = 400*100*1,1*1,5/2*0,47 = 70212 лм.

В светильнике типа ЛСП 01 можно применить, например люминесцентные лампы ЛХБ80 – со световым потоком Fл  = 4420 лм. При этом в ряду необходимо установить:

Nа = Fр/2*Fл = 70212/2*4220 = 8,31 следовательно 8 светильников.

Длинна светильника типа ЛСП 01 Lсв = 1536 мм. Тогда длинна одного ряда светильников.

1,536*8 = 12,29 м.

Проверяем, удовлетворяет ли проведённый расчёт осветительной установки допустимым отклонениям расчетной освещенности, Eрас от нормируемой величины Ен,

(не более, чем +20% \ -10%) [13]

Определяем освещенность, создаваемую расчетным количеством светильников, по формуле:

Ерас = Fл*nA*nB*n*h/S*z*kз = 4220*8*2*2*0.47/100*1.1*1.5 = 384 лк

Где n – количество ламп в светильнике ( для ЛСП 01 = 2), z – коэффициент минимальной освещённости, Кз – коэффициент запаса, h - коэффициент использования, относительных единицах.

Отклонение от нормируемой освещённости DЕ = Ен – Ерас = 16 лк, что составляет –0,86% от Ен.

Таким образом, 16 светильников типа ЛСП 01 – 2x80, размещенные по потолку в два ряда, обеспечивают требуемую освещенность рабочего мест.

  1.  Выводы

В процессе работы были сведены к минимуму негативные факторы, имеющие место при работе со средствами вычислительной техники.

Также в данной главе были детально рассмотрены основные требования, касающиеся компьютера пользователя и организации его рабочего места. Все эти требования соответствуют российским и международным стандартам организации работы пользователя средств вычислительной техники.

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


  1.  Экономико-организационная часть
    1.  Выбор аналога объекта разработки

Целью данной работы является анализ создания программно-аппаратного вычислительного комплекса повышенной надежности. Данный комплекс является узкоспециализированной системой, в настоящее время не имеющей аналогов. Целесообразность его разработки обусловлена  необходимостью обеспечения независимости Министерства Обороны РФ от иностранных производителей вычислительной техники и программного обеспечения.

  1.  Определение товарного типа объекта разработки

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

В результате был сделан вывод, что разработка относится к II товарному типу: разработки, выполняемые с коммерческой целью, предназначенные для прямой реализации, не имеющие рыночного аналога [14].

На основании товарного типа объекта разработки определяется состав расчетов в экономической части: смета затрат на разработку.

  1.  Определение трудоемкости выполнения разработки

Трудоемкость является одним из частных экономических показателей разработки. Она характеризуется временем труда определенного числа специалистов, необходимого для создания некоторого программного средства или выполнения некоторого этапа работ.

Трудоемкость определяется методом экспертных оценок по сумме трудоемкости этапов работ, выраженных в днях. Ожидаемое время выполнения работ Тож определяется по формуле:

Тож=(3·Tmin+2·Tmax)/5                                              (5.1)

где:

Tmin - минимально возможное время выполнения заданной работы;

Tmax - максимально возможное время.

Для определения трудоемкости необходимо составить перечень всех основных этапов, которые должны быть выполнены в процессе разработки. Расчет трудоемкости по формуле (5.1) для различных этапов разработки приведен в таблице 5.1.

п/п

Наименование этапов
разработки

Tmin,
Дней

Tmax,
Дней

Тож,
Дней

1

Анализ технического задания

3

6

4,2

2

Проектирование структуры программы

12

15

13,2

3

Разработка программной логики  

15

20

17

4

Кодирование системы

25

35

29

5

Отладка и тестирование программ

15

25

17

6

Создание документации

4

6

4,8

ВСЕГО:

74

107

85,2

Тблица 5.1 Трудоемкость выполнения разработки

  1.  Расчет сметы затрат на разработку

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

В состав сметной стоимости входят следующие статьи затрат:

• Стоимость вспомогательных материалов

• специальное оборудование для проведения разработки,

• основная заработная плата разработчиков,

• затраты на командировки,

• контрагентские работы,

• прочие затраты,

• накладные расходы.

• дополнительная заработная плата,

• отчисления на социальные нужды,

• затраты на электроэнергию для технологических целей,

Сметная стоимость определяется методом сметного калькулирования. Метод сметного калькулирования основан на прямом определении затрат по определенным статьям.

Стоимость вспомогательных материалов, руб.

(5.2)

где:

n - номенклатура применяемых покупных изделий и полуфабрикатов;

Ni - количество покупных изделий i-го вида;

Цi - цена покупного изделия i-го вида;

КТЗ - величина транспортно-заготовительных расходов КТЗ = 1,05

Затраты на покупные изделия приведены в таблице 5.2.

 

п/п

Перечень материалов

Единица измерения

Требуемое

кол-во

Цена за единицу, руб.

Сумма, руб.

Транспортно-заготовительные расходы

Итого затрат, руб

1

Бумага

Упаковка

1

120

120

1,05

126

2

Компакт-диски (CD-R)

Шт.

10

12

120

1,05

126

 

Итого:

 

 

 

240

 

252

Таблица 5.2 Стоимость вспомогательных материалов

 

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

                                                          (5.3)

где:

Цоб - балансовая стоимость ЭВМ (25 300 руб.);

НА - норма амортизационных отчислений (20% от стоимости ЭВМ);

tn - время использования оборудования для работы (81 день или 0,329 года).

Соб = 25300 · 0,2 · 0,329 = 1 665 руб.

Основная заработная плата (Сос) определяется по формуле:

                                                             (5.4)

где:

k   - количество категорий разработчиков;

- количество разработчиков данной категории;

 - среднечасовая   заработная   плата   j-той  категории разработчиков, руб.;

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

В  таблице  5.1  приведены  временные  затраты  на  разработку.
Реализация проекта осуществлялась двумя категориями разработчиков.
Это руководитель и программист, т.е. два человека.

Среднемесячная заработная плата руководителя проекта -  10000 рублей, а разработчика - 8000 рублей.

Длительность рабочего дня - 8 часов.

Количество рабочих дней в месяце - 22.

Основная зарплата разработчиков программы сведена в таблицу 5.4.

 

п/п

Наименование
этапов разработки

Тож,

дней

Исполнитель

Кол-во
человек

Зарплата,руб./день

Затраты, руб.

 

1

Анализ технического
 задания

4,2

Руководитель проекта

1

454,55

1 909,09

2

Проектирование структуры микропрограммы

13,2

Программист

1

363,64

4 800

3

Проектирование структуры программы

17

Программист

1

363,64

6 181,82

4

Кодирование

29

Программист

1

363,64

10 545,45

5

Отладка и тестирование программы

17

Программист

1

363,64

6 181,82

6

Создание документации

4,8

Программист

1

363,64

1 745,45

 

Общая сумма

85,2

 

 

 

31 363,63

Таблица 5.4 Основная заработная плата разработчиков

 

Сос=31 364 руб.

Дополнительная зарплата, руб.

Дополнительная зарплата исчисляется в расчете 10% от основной зарплаты.

Сдоп=Сос · 10%,                                                             (6.5)

Подставляя данные, получаем:

Сдоп=31 364 · 10%= 3 136,4 руб.

Отчисления в социальные фонды, руб.

Отчисления в социальные внебюджетные фонды составляют 26% на 1.01.2008 г.

Ссф=(Сос+Сдоп) · 0,26                                           (6.6)

Подставляя данные, получаем:

Ссф=(31 364+3 136) · 0,26= 8 970 руб.

 

Затраты на электроэнергию, потребляемую ЭВМ, руб.
СЭН =
W · Т · Сkr · Кwi,                                                  (6.7)

где:  W - установленная мощность ЭВМ (0,34 кВт);

Т - время использования для проведения разработки, час;

Сkr - цена одного кВт/ч электроэнергии, зависит от действующего в данное время тарифа, составляет 1 рубль 25 коп.;

Кwi - коэффициент использования мощности (0,9).

Учитывая, что функционирование ЭВМ подразумевается на всех этапах разработки кроме анализа технического задания, то время работы получается 81 день или 648 часов.

CЭН= 0,34 · 648 · 1,25 · 0,9 = 247,86 руб.

Накладные расходы, руб.

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

Сн= 31 364 · 0,7= 21 954,8 руб.

Прочие расходы, руб.

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

Сн= 31 364 · 0,1= 3 136,4 руб.

Полная себестоимость разработки

Полная себестоимость разработки сведена в Таблицу 5.4.

Наименование затрат

% от полной стоимости

Сумма, руб.

Стоимость вспомогательных материалов

0,4

252

Стоимость специального оборудования

2,4

1 665

Основная заработанная плата

44,3

31 364

Дополнительная заработанная плата

4,4

3 136

Отчисления в социальные фонды

12,7

8 970

Затраты на электроэнергию

0,4

248

Накладные расходы

31

21 955

Прочие расходы

4,4

3 136

Сумма:

 

70 726

Таблица 5.4 Полная себестоимость разработки системы

Технико-экономические показатели разработки приведены в таблице 5.5.

Наименование показателя

Единица измерения

Значение показателя

Технико-эксплуатационные показатели

Назначение программного продукта

 

Выполнение военных задач

Тип ЭВМ

 

Pentium-II 450 или старше

Операционная система

 

Linux

Минимальный объем оперативной памяти

Мбайт

128

Минимальный объем свободной памяти на HDD

Мбайт

100

Экономические показатели

Трудоемкость разработки

Чел.-дн.

85

Число разработчиков

Чел.

2

Сметная стоимость разработки

Руб.

70 730

Таблица 5.5 Технико-экономические показатели разработанной системы


  1.  ЗАКЛЮЧЕНИЕ

Микропрограммные и программные компоненты, разработанные в рамках дипломной работы, являются составной частью аппаратно-программного комплекса. Целесообразность их разработки подтверждается следующими положениями:

  •  микропрограмма содержит реализацию языка ассемблер и систему обработки прерываний, без которых комплекс неработоспособен;
  •  микропрограммные и программные компоненты отвечают за повышение надежности всего комплекса;
  •  обеспечена возможность «горячей замены» модулей без останова программы;
  •  полная стоимость разработки составила 70730 рублей, затраченная сумма укладывается в максимально отводимую для разработки;
  •  стратегическая выгода, связанная с независимостью Министерства Обороны РФ от иностранных производителей аппаратуры и программного обеспечения.


  1.  СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

  1.  Документация предприятия
  2.  В. А. Острейковский; Теория надежности: учебник для вузов - М. : Высшая школа, 2003.
  3.  Л.Константайн, Л. Локвуд; Разработка программного обеспечения - Питер, 2004 г., ISBN   5-88782-100-0, 0-201-92478-1
  4.  С. Прата; Язык программирования C. Лекции и упражнения – Вильямс, 2006 г., ISBN   5-8459-0986-4, 0-672-32696-5
  5.  Р. Брайант, Д. О'Халларон; Компьютерные системы: архитектура и программирование - БХВ-Петербург, 2005 г., ISBN   5-94157-433-9, 0-13-034074-X
  6.  Б. Уэлш, К. Джонс, Д. Хоббс; Практическое программирование на Tcl и Tk - Вильямс, 2004 г.,
    ISBN   5-8459-0661-X, 0-13-038560-3
  7.  Н. Вирт; Алгоритмы и структуры данных - Невский Диалект, 2005 г., ISBN   5-7940-0065-1
  8.  Д. Тейнсли; Язык shell. Linux и UNIX - БХВ-Петербург, 2005 г., ISBN   966-552-101-2, 5-7315-0130-0
  9.  И. Одинцов; Профессиональное программирование. Системный подход - БХВ-Петербург, 2006 г., ISBN 5-94157-457-6
  10.   Б. Керниган, Р. Пайк; Практика программирования - Вильямс, 2004 г., ISBN   5-8459-0679-2, 0-201-61586-X
  11.   А. Гриффитс; GCC. Полное руководство. Platinum Edition - ТИД "ДС", 2004 г., ISBN   966-7992-33-0, 0-07-222405-3
  12.   Г. Уоррен, мл.; Алгоритмические трюки для программистов - Вильямс, 2007 г., ISBN   5-8459-0572-9, 0-201-91465-4
  13.   Методические указания по выполнению раздела "Охрана труда" в дипломных проектах. – ЛИТМО, 1985.
  14.   Экономическая часть дипломных разработок: Методические указания для студентов технических специальностей всех форм обучения. – ЛИТМО, 1998.


Приложение 1

Текст микропрограммы

Файл Main.m

// Условная компиляция

// #define ZERO_DEBUG

// #define CALL_DEBUG

// #define INIT_DEBUG

// #define SAS_DEBUG

#define START_DELAY

#define MEMSIZE $34 // 13 Мб

#define DELAY_HI $4

#define DELAY_LO $93e0

#define EQ_IR

// #define ERR_TRAPPED

#define ERR_OPEN        // Открытые ошибки

#define TIMER_NEW

#define TIMER_HARD

// #define PRER14

// #define SOFT_ERROR   // программный обработчик ошибок

// #define IO_ERROR   // программный обработчик ошибок при работе с ВУ

#define VERSION              $210d

(

/*  Распределение 0-го килобайта ОЗУ (в байтах):

*

*  Начало | Конец | Длина |

*---------------------------------------------------------------------------

*  0x000  | 0x07F | 0x80  | Bекторы прерываний

*  0x080  | 0x1FF | 0x180 | ***FREE***

*  0x200  | 0x20F | 0x10  | отчет memtest

 *  0x210  | 0x37F | 0x170 | ***FREE***

*  0x380  | 0x383 |   4   | init DEBUG

*  0x384  | 0x3BF | 0x40  | ***FREE***

*  0x3C0  | 0x3C3 |   4   | init

*  0x3C4  | 0x3C7 |   4   | init DEBUG

*  0x3C8  | 0x3D3 |  12   | ***FREE***

*  0x3D4  | 0x3D7 |   4   | init

*  0x3D8  | 0x3DB |   4   | ***FREE***

 *  0x3DC  | 0x3DF |   4   | Идентификатор ВК (2 - СВК, 7 - АРМ)

*  0x3E0  | 0x3E3 |   4   | Копия РР

*  0x3E4  | 0x3FF | 0x1C  | ***FREE***

*  0x400  | 0x40B |  12   | Микрозагрузчик

*  0x40C  | 0x40F |   4   | ***FREE***

*  0x410  | 0x527 | 0x118 | Область выгрузки регистров

*  0x528  | 0x79F | 0x278 | ***FREE***

*  0x7A0  | 0x7A3 |   4   | Счетчик тиков таймера

*  0x7A4  | 0x7CF | 0x2C  | ***FREE***

*  0x7FC  | 0x7FF |   4   | Область выравнивания процессоров

*  0x800  | 0xAFF | 0x200 | ***FREE***

*  0xB00  | 0xBFF | 0x100 | ПКОС

*  0xC00  | 0xCFF | 0x100 | САС

*  0xD00  | 0xFFF | 0x400 | ***FREE***

 *         |       |       |

*---------------------------------------------------------------------------

*/

// Регистры

#define RonIE                RonR11

#define RonIM                RonR7

#define IR                   РПР

#define IM                   МРПР

#define ER                   РОШ

#define EM                   МРОШ

#define RonINL               RonMG

#define RonIX                RonSTBOR

#define RonIOS               RonNK

#define RonIBOT              RCC

#define RonILIM              OSP

#define RonLIM               RTC

#define RonIL                RonNL

#define RonIG                RonNG

#define RonMON               Ron40

#define RonID                Ron7F

#define RonIMcopy            writecon

#define RonEMcopy            Ron39

#define RonRamTest           jumpcont

#define RonPC                RonR2

#define RonNum               Ron46

#define RonMask              Ron47

// Полезные макросы

#define SAFERET              bdc; amk("*e00"); cjv(1,ATT)

#define MOV(R,H,L)           z +H=>R;e;R.cshl 16=>R;e;R+L=>R;e

#define ANAL(R,X)            R => .a2 skip; X => .b2 skip; e; anal(2)

#define EXCH(A,B,C)          A+z=>C;e;B+z=>A;e;C+z=>B;e

// Константы

#define TUPIK_FLAG           0              // маска тупика

#define IOEN_MIRROR_ADDR     $3E0           // зеркало регистра разрешения работы

#define RUNNING_FLAG         $ABC           // флаг начального запуска

#define HW_STACK_SIZE        64             // размер стека

#define HW_STACK_MASK        63             // маска стека

#define HW_FRAME_SIZE        16             // количество слов, которые должны быть свободны

// условие загрузки/выгрузки стека HWSTACK_SIZE - (HW_FRAME_SIZE + 1)

#define TOP_MINUS_BOT        47

#define IS_READY             $5500          // признак свободной магистрали

#define IS_BUSY              $0000          // признак занятой магистрали

#define MAXLEN               $c350          // максимальный размер операнда длинной команды

// счетчики

#define TICK_COUNTER_ADDR    $7a0           // Таймер

#define ERR14_COUNTER_ADDR   $c00

#define PRER0_COUNTER_ADDR   $c04

#define PRER1_COUNTER_ADDR   $c08

#define PRER2_COUNTER_ADDR   $c0c

#define PRER3_COUNTER_ADDR   $c10

#define PRER4_COUNTER_ADDR   $c14

#define PRER5_COUNTER_ADDR   $c18

#define PRER6_COUNTER_ADDR   $c1c

#define PRER7_COUNTER_ADDR   $c20

#define PRER8_COUNTER_ADDR   $c24

#define PRER9_COUNTER_ADDR   $c28

#define PRERA_COUNTER_ADDR   $c2c

#define PRERB_COUNTER_ADDR   $c30

#define PRERC_COUNTER_ADDR   $c34

#define PRERD_COUNTER_ADDR   $c38

#define MEM_ERR_INFO_ADDR    $c80           // инф о последней ошибке

#define PR_ERR_INFO_ADDR     $c84           // инф о последней ошибке

#define PR_MASK_ADDR         $c88           // текущие маски

#define PR_EQUALIZER_ADDR    $c8c // область выравнивания процессоров

#define PR_EQUALIZER_VALUE $4321 // значение для выравнивания процессоров

#define REPAIR_MODE_ADDR     $f00

// маски магистралей

#define CH1_MASK             1

#define CH2_MASK             2

#define CH3_MASK             4

#define RUN_MASK             7

#define STEP_MODE_MASK $1000  // маска пошагового режима      в РОШ

#define EQUALIZE_MODE_MASK $2000 // маска режима выравнивания в РОШ

#define START_MODE_MASK   $2000 // маска начального запуска     в РОШ

#define TA_INTERRUPT_MASK $3000  // маска прерывания ТА-002      в РПР

#define TA_START_MAS  $1000         // маска начала обмена          в РПР

#define TA_FINISH_MASK   $2000         // маска окончания обмена       в РПР

#define TIMER_INTERRUPT_MASK $8000 // маска таймерного прерывания  в РПР

#define ERROR_INTERRUPT_MASK $4000 // маска прерывания по ошибке   в РПР

#define VK_ID_ADDR           $3DC      // Идентификатор BК: 7 - АРМ, 2 - СBК

// Bекторы прерываний

#define IVECT_NULL_REF  $78 // обращение к нулевому адресу ОЗУ      

#define IVECT_HANG_UP   $74       // ошибка ввода/вывода                  

#define IVECT_DIV0           $70           // деление на ноль                      

#define IVECT_SAOVR        $6c          // переполнение стека                  

#define IVECT_INIT           $68     // неперавильный аргумент команды init   

#define IVECT_IOC          $48    // прерывание от внешнего устройства   

// Значения по умолчанию для служебных регистров

#define X_DEFAULT_VALUE      $e000

#define L_DEFAULT_VALUE      $e000         // область данных процедуры

#define G_DEFAULT_VALUE      $0000         // область данных программы

#define OSI_DEFAULT_VALUE    $f000         // область сохранения стека

#define LIM_DEFAULT_VALUE    $7ff    // размер области сохранения стека

#define TOPI_DEFAULT_VALUE   17            // вершина стека

#define BOTI_DEFAULT_VALUE   0             // дно стека

// коды команд микрозагрузчика

// Команда/ответ микрозагрузчика

#define caCmdLo $400

#define caCmdHi $0000

#define caDumpLo   $410    // Область выгрузки состояния процессора

#define caDumpHi             $0000

#define caAddrLo             $404          // Параметр-адрес

#define caAddrHi             $0000

#define caLengthLo           $408          // Параметр-длина

#define caLengthHi           $0000

#define caPcLo               $41c          // Значение PC

#define caPcHi               $0000

#define RAM_TEST_MODE        $CE

// коды возврата микрозагрузчика

#define mlMLState            $00        // в режиме микрозагрузчика

#define mlOk                 $01           // Команда выполнена

#define mlBreak              $02           // Останов по break

#define mlTrace              $03           // Останов по step

#define mlNull               $04           // NULL

#define mlFail               $0F           // Ошибка

// Адреса информации об ошибке для программного обработчика

#define DEVICE_TYPE_ADDR     $800

#define CHANNEL_NUMBER_ADDR  $804

#define ERROR_TYPE_ADDR      $808

//-----------------------------------------------------

#include "zero.m"       // начальный запуск

// Система команд

#include "mkdiv.m" // команды деления

#include "mkmul.m" // команды умножения

#include "mkcomp.m"       // команды сравнения

#include "mkstack.m" // команды работы со стеком

#include "mkbit.m" // команды битовых операций

#include "mkadd.m" // команды сложения/вычитания

#include "mkaddr.m"       // команды формирования адреса

#include "mkload.m"       // команды загрузки слов на вершину стека

#include "mkloadh.m"    // команды загрузки полуслов на вершину стека

#include "mkloadb.m"      // команды загрузки байтов на вершину стека

#include "mkstore.m"      // команды выгрузки слов с вершины стека

#include "mkstoreh.m"   // команды выгрузки полуслов с вершины стека

#include "mkstoreb.m"     // команды выгрузки байтов с вершины стека

#include "mkjmp.m"        // команды переходов

#include "mkloop.m"       // команды циклов

#include "mklog.m" // команды логических операций

#include "mkmisc.m"       // прочие команды

#include "mkstr.m"        // строковые команды

#include "mkspecr.m"    // команды работы со спецрегистрами L, G, X

#include "mkcall.m"       // команды вызова процедуры

#include "mkret.m"        // команды возврата из процедуры

#include "mkint.m"        // команды обработки прерываний

#include "mkinit.m"       // команда init

#include "mkprs.m"        // команды переключения контекста задач

#include "mk16.m"  // шлюз для двухбайтовых команд

#include "mkdev.m"        // команды работы с внешними устройствами

#include "mksas.m"

#include "mkir.m"         // команды работы с РПР

#include "mker.m"         // команды работы с РОШ

#include "prer.m"         // обработчик аппаратных прерываний

#include "prerta.m"       // обработчик прерываний ТА-002

#include "prerstep.m"     // обработчик пошагового режима

#include "prerfix.m"      // обработчик прерывания выравнивания

#include "romload.m"      // запуск из ПЗУ

#include "traps.m" // ловушки

#include "except.m" // исключительные ситуации

#include "fz.m"           // микрозагрузчик

#include "mlstart.m"      // запуск программы

#include "mlsync.m"       // выравнивание ОЗУ

#include "mlstep.m"       // шаг программы

#include "mlcont.m"       // продолжение остановленной программы

#include "mlclear.m"      // очистка ОЗУ

#include "raminit.m"      // инициализация КП-001

#include "rginit.m"       // инициализация регистров

#ifdef TIMER_HARD

 #include "ticker_h.m"     // таймер аппаратный

#else

 #include "ticker.m"       // таймер

#endif

#include "rgdump.m"       // выгрузка регистров в ОЗУ

#include "diag.m"

#include "poweron.m"

#include "equalpr.m"      // выравнивание процессоров

m("finish");

.skip

)

Файл diag.m

M("*f52");

 z + 2 => R2; e;

 I(Up); jmp("diagld");

M("*f41");            // diagnostic

  e;

  z + pip1 -> R2 => .b2 skip; e;

  R2 => .b1 skip; R2 => .b2 skip; amk("*d40"); Cjv(1,AAD);

m("*d40"); jmp("ins_cpu");  // ввод процессора

m("*d41"); R2 + z -> Q; jmp("diagld");

m("*d42"); R2 + z -> Q; jmp("diagld");

m("*d43"); jmp("*f42");                         // портит процессор

m("*d44"); R2 + z -> Q; jmp("diagld");

m("*d45"); I(S;down); jmp("diag41");            // тестирует процессоры

m("*d46"); jmp("diagMJ");         // порождает ошибку в выходном мажоритаре

m("*d47"); RonID + z -> Q; jmp("diagld");

m("*d48"); jmp("*d48");

m("*d49"); e;

 7 .and R2 -> R2; jmp("diagst");

m("*d4a"); e;

 7 .and R2 -> R2; jmp("diagst");

m("*d4b"); jmp("*d4b");

m("*d4c"); e;

 7 .and R2 -> R2; jmp("diagst");

m("*d4d"); jmp("*d4d");

m("*d4e"); I(Down); e;

          RonIMcopy => Is; ret;

m("*d4f"); jmp("spoilPC");              // портит Pc

//----------------------------------------------------------------------------

/*

* Загрузка данных из конкретного ОЗУ

* Параметры:

* R2 - значение MON-ов

* Is - адрес памяти

* Результат:

* Is - значение

*/

m("diagld");

 push($20); rfst;

 z + $18 => Arb; e;

 Q + z => Mon; e;

 Is + z => Ba; e;

 cjmp(zc, "nullref");

 read; e; blk1; e;

 Bd + z => Is; e;

 z + RonMON => Mon; e;

 z + 8 => Arb; e;

 0 => ER; I(Down); e;

 ret;

//----------------------------------------------------------------------------

m("diagst");

 push($20); rfst;

 z + $18 => Arb; e;

 R2 => Mon; e;

 Is + z => Ba; e;

 cjmp(zc, "nullref");

 write4; I(S1; down) + z => BD; e;

 0 => Is; blk0; e;

 z + RonMON => Mon; e;

 0 => ER; e;

 z + $8 => Arb; e;

 SAFERET;

//-------------------------------------------------------------------

M("0ret");     z + z => ER; Ret;

//-------------------------------------------------------------------

M("*f43");  // портит память

 z + z => R1; c1; e;

 Is => Sd_n; e;

 .shl R1 => R1; e;

 z + 4 => Ba; e;

 read; e; blk1; e;

 Bd + 1 => R2; e;

 push (20); rfst;

 z + $18 => Arb; e;

 R1 => Mon; e;

 R2 => Bd; e;

 write4; e; blk0; e;

 z + RonMON => Mon; e;

 z + $8 => Arb; e;

 I(Down;S1)=>Is; e;

 ret;

//-------------------------------------------------------------------

M("*f42");  // портит процессор

 e;

 Arb + z => R3; e;

 R3 .cshl 29 => R3; e;

 R3 .and 3 => R3; e;

 // Боремся перепутанными номерами

 3 - R3 -> R3; cjmp(^zc, "^1st2-2");

 z + z -> R3; jmp("both-2");

m("^1st2-2");

 e;

m("both-2");

 Is - R3 -> Q; e;

 I(Down;S1)=>Is; cjmp (^zc, "f42ret");

 jmp ("*cab");

M("f42ret");

 SAFERET;

//-------------------------------------------------------------------

M("diag41"); I(S1;down)=> IS; jmp("*f41");

 Pc + z => RonPC; e;

 z + z -> R1; Js("===");

  R1 .cshl 16 => R1; e;

  Is => I(Up;S); e;

  R1 + Ron R1 => Is; e;

 z + EM -> R2; e;

 RonPC + z => Pc; jmp ("IRET+");

//-------------------------------------------------------------------

M("diagMJ");  // порождает ошибку в выходном мажоритаре

 Arb + z => R3; e;

 R3 .cshl 29 => R3; e;

 R3 .and 3 => R3; e;

 Is - R3 -> Q; e;

 Q + z; ron zero => .up R3; Alu Eq; e;

 R3 + z; e;

 I(Down); cjmp (^zc,"DfOut");

 I(S) + z => R3; e;

M("DfOut");

 z + PR_EQUALIZER_ADDR => Ba; e;

 z + R3 => Bd; e;

 write4; e; blk0; e;

 z + z -> Q => R3; e;

 z + ER => Is; Ret;

//-------------------------------------------------------------------

M("*f51");

 e;

 push($20); rfst;

 z + $18 => Arb; e;

M("LoopF51");

 e;

 Is - z => Is; C0; e;

 Is + z; e;

 cjmp(^f32c,"LoopF51");

 I(Down;S1) => Is; e;

 z + RonMON => Mon; e;

 z + 8 => Arb; e;

 z + z => ER; e;

 SAFERET;

M("diagMG");

 Ret;

Файл equalpr.m

M("======");

 z + z => ER; e;

 z + 7 => Mon; e;

 z + PR_EQUALIZER_ADDR => Ba; e;

 write4; z + 1 => Bd; e;

 blk0; e; e;                   // Делаем контрольный обмен

 z + z => Bd; e;

 z + PR_EQUALIZER_ADDR => BA; e;

 read; e; blk1; e;

 Bd - 1; e;

 cjmp(zc, "===1");

 R1 .or EQUALIZE_MODE_MASK -> R1; e;

 R2 .or EQUALIZE_MODE_MASK -> R2; e;

 R1 => ER; e;

 R2 => EM; e;

 Ron42 - 1; e;

 cjmp(zc, "*cab");          

 z + z => ER; e;

 z + $8 => Arb; e;

 R2 .andnot EQUALIZE_MODE_MASK -> R2; e;

 R2 => EM; e;

 jmp("iret");

M("===1");

 // выравниваем регистры

 js("===");

 EM => R2; e;

 // обрабатываем результаты выравнивания

 // Проверяем, были ли обнаружены испорченные регистры

 jmp ("=no_err");

 // Если да - сохраняем в памяти номер первого испорченного

 z + PR_ERR_INFO_ADDR -> Q => BA; e;

 RonR1 => Bd; write4; e;

 blk0; e;

M("=no_err");

 // Проверяем, не было ли неудачи при выравнивании

 RonR1 + z => .a2 skip; e;

 cjmp (da31c, "---pr");

 // Выровнять регистры удалось

 // Возвращает маску ошибок процессоров

 R2 .or 7 -> R2; e;

 R2 .andnot EQUALIZE_MODE_MASK -> R2; e;

 R2 => EM; e;

 z + z => Pc; e;

 z + z => Ron42; e;

 z + z => Ron43; e;

 z + z => ER; e;

 RonMON => Mon; e;

 z + 8 => Arb; e;

 jmp ("iret");

 // Выровнять регистры не получилось

M("---pr");  jmp("---pr");

//--------------------------------------------------------------------------

// Восстановление процессора

M("===");            // на входе: RonPC - сохр РС

                    // RonR3 - номер регистра

                    // RonR4 - рабочий

                    // RonR5 - рабочий

                    // на выходе: RonR1 -номер ошибки

 z + z => RonR1; e;

 z + z => RonR3; e;

#define EQUAL_REG(R) R     => RonR4; js("==RR=="); Bd     => R; e

#define EQUAL_RON(R) R     -> RonR4; js("==RR=="); Bd     => R; e

#define EQUAL_A(R)   R + z => RonR4; js("==RR=="); Bd + z => R; e

#define EQUAL_B(R)   z + R => RonR4; js("==RR=="); Bd + z => R; e

#define EQUAL_Q      Q + z => RonR4; js("==RR=="); Bd + z -> Q; e

#define EQUAL_S(R)   R + z => RonR4; js("==RR=="); Bd     => R; e

M("=L   "); EQUAL_REG(L);

M("=G   "); EQUAL_REG(G);

M("=Rcom"); z + RUNNING_FLAG -> Rcom; e;

M("=Is  "); EQUAL_REG(Is);

M("=R1  "); EQUAL_REG(R1);

M("=R2  "); EQUAL_REG(R2);

M("=R3  "); EQUAL_REG(R3);

M("=R4  "); EQUAL_REG(R4);

M("=TopI"); EQUAL_S(TopI);

M("=TopA"); EQUAL_S(TopA);

M("=TopP"); EQUAL_S(TopP);

M("=BotI"); EQUAL_S(BotI);

M("=BotA"); EQUAL_S(BotA);

M("=BotP"); EQUAL_S(BotP);

M("=EM"); EQUAL_B(EM);

M("=ER"); EQUAL_B(ER);

M("=IM"); EQUAL_B(IM);

M("=IR"); EQUAL_B(IR);

M("=Q   "); EQUAL_Q;

M("=Ron0 "); EQUAL_RON(Ron0);

M("=Ron1 "); EQUAL_RON(Ron1);

M("=Ron2 "); EQUAL_RON(Ron2);

M("=Ron3 "); EQUAL_RON(Ron3);

M("=Ron4 "); EQUAL_RON(Ron4);

M("=Ron5 "); EQUAL_RON(Ron5);

M("=Ron6 "); EQUAL_RON(Ron6);

M("=Ron7 "); EQUAL_RON(Ron7);

M("=Ron8 "); EQUAL_RON(Ron8);

M("=Ron9 "); EQUAL_RON(Ron9);

M("=Ron10"); EQUAL_RON(Ron10);

M("=Ron11"); EQUAL_RON(Ron11);

M("=Ron12"); EQUAL_RON(Ron12);

M("=Ron13"); EQUAL_RON(Ron13);

M("=Ron14"); EQUAL_RON(Ron14);

M("=Ron15"); EQUAL_RON(Ron15);

M("=Ron16"); EQUAL_RON(Ron16);

M("=Ron17"); EQUAL_RON(Ron17);

M("=Ron18"); EQUAL_RON(Ron18);

M("=Ron19"); EQUAL_RON(Ron19);

M("=Ron20"); EQUAL_RON(Ron20);

M("=Ron21"); EQUAL_RON(Ron21);

M("=Ron22"); EQUAL_RON(Ron22);

M("=Ron23"); EQUAL_RON(Ron23);

M("=Ron24"); EQUAL_RON(Ron24);

M("=Ron25"); EQUAL_RON(Ron25);

M("=Ron26"); EQUAL_RON(Ron26);

M("=Ron27"); EQUAL_RON(Ron27);

M("=Ron28"); EQUAL_RON(Ron28);

M("=Ron29"); EQUAL_RON(Ron29);

M("=Ron30"); EQUAL_RON(Ron30);

M("=Ron31"); EQUAL_RON(Ron31);

M("=Ron32"); EQUAL_RON(Ron32);

M("=Ron33"); EQUAL_RON(Ron33);

M("=Ron34"); EQUAL_RON(Ron34);

M("=Ron35"); EQUAL_RON(Ron35);

M("=Ron36"); EQUAL_RON(Ron36);

M("=Ron37"); EQUAL_RON(Ron37);

M("=Ron38"); EQUAL_RON(Ron38);

M("=Ron39"); EQUAL_RON(Ron39);

M("=Ron40"); EQUAL_RON(Ron40);

M("=Ron41"); EQUAL_RON(Ron41);

M("=Ron42"); EQUAL_RON(Ron42);

M("=Ron43"); EQUAL_RON(Ron43);

M("=Ron44"); EQUAL_RON(Ron44);

M("=Ron45"); EQUAL_RON(Ron45);

//M("=Ron46"); EQUAL_RON(Ron46);

//M("=Ron47"); EQUAL_RON(Ron47);

M("=Ron48"); EQUAL_RON(Ron48);

M("=Ron49"); EQUAL_RON(Ron49);

M("=Ron50"); EQUAL_RON(Ron50);

M("=Ron51"); EQUAL_RON(Ron51);

M("=Ron52"); EQUAL_RON(Ron52);

M("=Ron53"); EQUAL_RON(Ron53);

M("=Ron54"); EQUAL_RON(Ron54);

M("=Ron55"); EQUAL_RON(Ron55);

M("=Ron56"); EQUAL_RON(Ron56);

M("=Ron57"); EQUAL_RON(Ron57);

M("=Ron58"); EQUAL_RON(Ron58);

M("=Ron59"); EQUAL_RON(Ron59);

M("=Ron60"); EQUAL_RON(Ron60);

M("=Ron61"); EQUAL_RON(Ron61);

M("=Ron62"); EQUAL_RON(Ron62);

M("=Ron63"); EQUAL_RON(Ron63);

M("=TMR");   // выравнивание таймера

 js("tmr_init");

 // Обнуление таймера гладкого счета

 RST; e;

 e;

 z + z => .b2 skip; Ld4; e;

 z + z => .b2 skip; Ld4; e;

M("==I");

 TopI + z -> R4; e;

 z + 63 -> R1; e;

 R1 => TopI; e;

 z + PR_EQUALIZER_ADDR => BA; e;

 push(63);

   I(S) + z => Bd; e;

   write4; e; blk0; e;

   read; e; blk1; e;

   Bd => I(S); e;

   I(down); e;

   RonR3 + 1 => RonR3;

 rfst;

 R4 => TopI; e;

 crtn(1);

M("==RR==");

                    // на входе: RonR4 - ?значение

                    // на входе: RonR3 - номер рег

                    // на входе: RonR1 - код ошибки

 z + PR_EQUALIZER_ADDR => BA; e;

 RonR4 => Bd; write4; e;

 RonR3 + 1 => RonR3; blk0; e;

 z + PR_EQUALIZER_ADDR => BA; e;

 read; e; blk1; e;

 crtn(1);

Файл except.m

M("sovf"); jmp("*cab");  // переполнение области выгрузки стека

//--------------------------------------------------------------------

// Ошибка магистрали при работе с ВУ

M("io_err");

 z + RonMON => Mon; e;

 z + $8 => Arb; e;

 z + IVECT_HANG_UP => Ron R3; e;

 js("hw");

 Ret;

//--------------------------------------------------------------------

// прерывание при делении на 0

M("dbz");

 z + IVECT_DIV0 => Ron R3; e;

 js("hw");

 ret;

//--------------------------------------------------------------------

// прерывание при обращении к нулевому адресу

M("nullref");

 ER => R1; e;

 EM => R2; e;

 Pc => R3; e;

 RonPC => R4; e;

 ANAL(R1, $1111);

 ANAL(R2, $2222);

 ANAL(R3, $3333);

 ANAL(R4, $4444);

 z + IM => RonIMcopy; e;

 z + z => IM; e;

 z + EM => RonEMcopy; e;

 z + z => EM; e;

 push ($20); rfst;

 z + $18 => Arb; e;

 PC - z => RonPC; c0; e;

 RonPC + z => Pc; e;

 js("RgDump");

 z + 4 => R4; e;

 jmp("fz");

//--------------------------------------------------------------------

// Ошибочный аргумент команды init

M("init_err"); jmp("init_err");

//--------------------------------------------------------------------

// Переполнение программного стека

M("allocerr");

// Запись адреса функции, вызвавшей переполнение стека

 z + $3d4 => Ba; e;

 R2 - 1 => Bd; e;

 write4; e; blk0; e;

 z + $3c0 => Ba; e;

 z + RonLIM => Bd; e;

 write4; e; blk0; e;

 z + $7c => Ron R3; e;

 Ron R3 => Ba; e;

 read; e; blk1; e;

 Bd => R3; e;

 z + R3; e;

 cjmp(zc, "a_noerr");

 Pc => R2; e;

 js ("hw");

 ret;

Файл fz.m

/*

* Микрозагрузчик:

* .................

*

* Адрес команды: 0x400

* Признак команды: 1 в 7-м бите

* Коды команд (не считая седьмого бита):

*

* 00 - NOP (пустая операция)

* 0A - переход в режим тестирования ОЗУ

* 01 - Start (запуск с адреса, лежащего по адресу 0)

* 02 - Continue (запуск с адреса, лежащего по адресу caPcLo)

* 03 - ResetRegs (установка регистров в исходное состояние)

* 04 - Sync (синхронизация каналов)

*

* Используемые регистры:

* R4       - код команды

*/

m("*e00");

 z + IM => RonIMcopy; e;

 z + z => IM; e;

 z + EM => RonEMcopy; e;

 z + z => EM; e;

 push ($20); rfst;

 z + $18 => Arb; e;

 PC - z => RonPC; c0; e;

 RonPC + z => Pc; e;

 js("RgDump");

 z + mlBreak => R4; e;

 jmp("fz");

m("*e01"); jmp("*e00");

M("fz");

 z + RonMON => Mon; e;

M("==>>+");                   // главный цикл микрозагрузчика

 R4 .and $FF => R4; e;

 MOV(R1, caCmdHi, caCmdLo);

 R1 => Ba; e;

 R4 => BD; write4; e;

 blk0; e;

 z + caCmdLo => R1; c1; e;

 R1 => Pc; e;

 z + $18 => Arb; e;

m("ml");

 z + TA_START_MASK => R1; e;

 R1 => IM; e;

 z + RonID => Mon; e;

 z + caCmdLo => Ba; e;

 read; e; blk1; e;

 BD .and $ff => R4; e;

 z + RonMON => Mon; e;

m("mlcheck");

 R4 => .a2 skip; e;

 cjmp(^da7c, "mlcnt");   // проверка есть ли команда

 z + caCmdLo => Ba; e;

 write4; e; blk0; e;

 // ветвление по команде

 R4 => .b1 skip; R4 => .b2 skip; amk("*db0"); cjv(1,AAD);

m("mlcnt");

 IR => R3; e;

 prer; jmp("ml");

// NOP

m("*db0");

 e;

 js ("rgdump");

 z + mlOk => R4; jmp("==>>+");

m("*db1"); jmp("mlStart");

m("*db2"); jmp("mlCont");

// ResetRegs

m("*db3"); jmp("*db3");

m("*db4"); jmp("mlSync");

m("*db5"); jmp("mlStep");

m("*db6"); jmp("*db6");

m("*db7"); jmp("*db7");

m("*db8"); jmp("*db8");

m("*db9"); jmp("*db9");

m("*dba"); jmp("*dba");

m("*dbb"); jmp("*dbb");

m("*dbc"); jmp("*dbc");

m("*dbd"); jmp("*dbd");

m("*dbe"); jmp("loadROM");

m("*dbf"); jmp("*dbf");

Файл mk16.m

// Шлюз для двухбайтовых команд

m("$k16");

  bdc; Dcd16;  // чтение полуслова из конвейера

Файл mkadd.m

// Команды операций сложения/вычитания

// Мнемоника команды: inc

m("$inc");

 1 + Is -> Is; ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: dec

m("$dec");

 Is - z -> Is; c0; ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: neg

m("$neg");

 z - Is -> Is; ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: abs

m("$abs");

 Is => .a2 skip; e;

 cret(^da31c);

 z - Is -> Is; repret;

//-----------------------------------------------------------------------------

// Мнемоника команды: add

m("$add");

 I(S1) + Is -> Is; I(Down); ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: sub

m("$sub");

 I(S1) - Is -> Is; I(Down); ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: rsub

m("$rsub");

 Is - I(S1) ->Is; I(Down); ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: add i8

m("$addi");

 Is + Pip1 -> Is; e;

 ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: sub i8

m("$subi");

 Is - Pip1 -> Is; e;

 ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: rsub i8

m("#RSUBI");

 z + Pip1 -> R1; e;

 R1 - Is -> Is; ret;

Файл mkaddr.m

// Команды формирования адреса на вершине стека

// Мнемоника команды: fa L8

M("$FAL8");

 L + Pip1 => RonR1; e;

 z + RonR1 => Is; Is => I(Up;S); Ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: fa L16

M("$FAL16");

 L + Pip2 => Ron R1; e;

 z + Is => I(Up;S); e;

 z + RonR1 -> Is; Ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: fa G8

M("$FAG8");

 G + Pip1 => RonR1; e;

 z + RonR1 => Is; Is => I(Up;S); Ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: fa G16

M("$FAG16");

 G + Pip2 =>Ron R1; e;

 z + Is => I(S); I(Up); e;

 z + RonR1 => Is; Ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: fa G32

M("$FAG32");

 Is + z => I(Up;S); e;

 z + Pip2 => Is; e;

 Is .cshl 16 => Is; e;

 Is + Pip2 => Is; e;

 Is .cshl 16 => Is; e;

 G + Is => Is; e;

 Ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: fa r8

M("$FAR8");

 z + Pip1 => .a2 R1; e;

 Is => I(Up;S); cjs(da7c,"FR8P");

 Pc + R1 -> Is; Ret;

M("FR8P");

 R1 .ornot Ron R9 => R1; crtn(1);

//-----------------------------------------------------------------------------

// Мнемоника команды: fa r16

M("$FAR16");

 z + Pip2 => .a2 R1; e;

 Is => I(Up;S); CJs(da15c,"FR16P");

 Pc + R1 -> Is; Ret;

M("FR16P");

 R1 .ornot Ron LW -> R1; e; crtn(1);

Файл mkbit.m

// Команды битовых операций

// Мнемоника команды: sxtb

m("$sxtb");

 Is => .a2 skip; e;

 Is .and Ron R9 -> Is; cret(^da7c);

 Is .ornot Ron R9 -> Is; repret;

//-----------------------------------------------------------------------------

// Мнемоника команды: sxth

m("$sxth");

 Is => .a2 skip; e;

 Is .and Ron Lw -> Is; cret(^da15c);

 Is .ornot Ron Lw -> Is; repret;

//-----------------------------------------------------------------------------

// Мнемоника команды: zxtb

M("$zxtb");

 Ron R9 .and Is -> Is; ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: zxth

M("$zxth");

 Ron Lw .and Is -> Is; ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: ext i8,i8

// 1-й аргумент - исходная позиция поля

// 2-й аргумент - размер поля

M("$ext");

 z - Pip1 => Sd_n; e;

 .shl Is => Ron R1; z + 1 -> R1; e;

 z + Pip1 => Sd_n => R2; e;

 .shl R1 => R1; cjmp(zc, "ext_wd0");

 z - R2 => Sd_n; e;

 .shl Ron R1 => .a2 skip; R1 - 1 -> R1; e;

 Ron R1 .and R1 -> Is; cret(^da31c);

 Ron R1 .ornot R1 -> Is; repret;

M("ext_wd0");

 z + z -> Is; ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: extu i8,i8

// 1-й аргумент - исходная позиция поля

// 2-й аргумент - размер поля

m("$extu");

 z - Pip1 => Sd_n; e;

 .shl Is => Ron R1; z + 1 -> R1; e;

 z + Pip1 => Sd_n; e;

 .shl R1 => R1; e;

 R1 - 1 -> R1; e;

 Ron R1 .and R1 -> Is; ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: ins i8,i8

// 1-й аргумент - исходная позиция поля

// 2-й аргумент - размер поля

m("$ins");

 z + Pip1 -> R2; e;

 z + 1 => R1; e;

 z + Pip1 => Sd_n; e;

 .shl R1 => R1; e;

 z - R1 => R1; e;

 R2 => Sd_n; e;

 Is .andnot R1 -> Is; e;

 .shl R1 => R1; e;

 .shl Is => Is; e;

 I(Down;S1) .and R1 -> R1; e;

 R1 .or Is -> Is; ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: rins i8,i8

// 1-й аргумент - исходная позиция поля

// 2-й аргумент - размер поля

m("$rins");

 z + Pip1 -> R2; e;

 z + 1 => R1; e;

 z + Pip1 => Sd_n; e;

 .shl R1 => R1; e;

 z - R1 => R1; e;

 R2 => Sd_n; e;

 I(S1) .andnot R1 => R2; I(Down); e;

 .shl R1 => R1; e;

 .shl R2 => R2; e;

 Is .and R1 -> Is; e;

 Is .or R2 -> Is; ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: shl

m("$shl");

 Is => Sd_n; z + 1 -> R1; e;

 .shl R1 => R1; e;

 .shl I(S1) => I(S1); R1 - 1 -> R1; e;

 I(Down;S1) .andnot R1 -> Is; Ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: shl i8

m("$shli");

 z + Pip1 => Sd_n; e;

 z + 1 -> R1; e;

 .shl R1 => R1; e;

 .shl Is => Ron R1; z - R1 -> R1; e;

 Ron R1 .and R1 -> Is; ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: shr

m("$shr");

 z - Is => Sd_n; I(Down;S1) => Is; e;

 z + z -> R1; c1; cret(zc);

 .shl R1 => R1; e;

 .shl I(S) => I(S); R1 - 1 -> R1; e;

 I(S) .and R1 -> Is; repret;

//-----------------------------------------------------------------------------

// Мнемоника команды: shr i8

m("$shri");

 z - Pip1 => Sd_n; e;

 z + z -> R1; c1; cret(zc);

 .shl R1 => R1; e;

 .shl Is => Ron R1; z - R1 -> R1; e;

 Ron R1 .andnot R1 -> Is; repret;

//-----------------------------------------------------------------------------

// Мнемоника команды: ashr

M("$ashr");

 z - Is => Sd_n; I(Down;S1) => Is; e;

 z + z -> R1; c1; Is => .a2 skip; cret(zc);

 .shl R1 => R1; cjmp(da31c, "ash1");

 .shl I(S) => I(S); R1 - 1 -> R1; e;

 I(S) .and R1 -> Is; repret;

m("ash1");

 .shl I(S) => I(S); R1 - 1 -> R1; e;

 I(S) .ornot R1 -> Is; repret;

//-----------------------------------------------------------------------------

// Мнемоника команды: ashr i8

M("$ashri");

 z - Pip1 => Sd_n; e;

 z + z -> R1; c1; Is => .a2 skip; cret(zc);

 .shl R1 => R1; cjmp(da31c, "ashi1");

 .shl Is => Ron R1; z - R1 -> R1; e;

 Ron R1 .andnot R1 -> Is; repret;

m("ashi1");

 .shl Is => Ron R1; z - R1 -> R1; e;

 Ron R1 .or R1 -> Is; repret;

Файл mkcall.m

// Команды вызова процедуры

// Мнемоника команды: call r16

M("$CALLR");

 z + Pip2 => RonPC; e;

 Pc + z => Ron R4; e;

 RonPC => .a2 skip; e;

 cjmp(^da15c,"CRP");

 RonPC .ornot Ron Lw => RonPC; e;

M("CRP");

 Ron R4 + z -> R4; e;

 RonPC + R4 => RonPC; e;

 cjmp(zc, "nullref");

 RonPC + z => Pc; e;

 BotI .and $fff -> Q => R2; e;

 Is + z => I(Up;S); e;

 R2 + 48 -> R2; e;

 TopI .and $fff -> R1; e;

 R2 - R1 => .a2 R2; e;

 cjs(da31c, "cflush");

 Ron R4 + z => Is; e;

 Ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: call im32

M("$CALLI");

 z + Pip2 -> R2; e;

 Is => .a2 skip; $0000 => .b2 skip; e;

 z + Pip2 -> R3; e;

 Pc + z -> R4; e;

 R3 .cshl 16 => R3; e;

 R2 + R3 -> R2; e;

 cjmp(zc, "nullref");

 R2 + z => Pc; e;

 BotI .and $FFF -> Q => R2; e;

 Is + z => I(Up;S); e;

 R2 + 48 -> R2; e;

 TopI .and $FFF -> R1; e;

 R2 - R1 => .a2 R2; $0000 => .b2 skip; e;

 cjs(da31c,"CFLUSH");

 R4 + z -> Is; e;

 Ret;

//-----------------------------------------------------------------------------

// Мнемоника команды: calls

M("$CALLS");

 Pc + z -> R4; e;

 Is + z; e;

 cjmp(zc, "nullref");

 Is + z => Pc; e;

 BotI .and $FFF -> Q => R2; e;

 TopI .and $FFF => R1; e;

 R2 - R1 -> R2; e;

 R2 + 48 => .a2 R2; e;

 cjs(da31c,"CFLUSH");

 R4 + z -> Is; e;

 Ret;

//--------------------------------------------------------------------

/*

* Процедура выгрузки регистрового стека в ОЗУ

*

* Входные регистры:

* OSI  - адрес области сохранения

* Q  - значение указателя дна стека

* R2  - отрицательное значение, равное по модулю количеству

*    отгружаемых регистров

*

* Используемые регистры:

* Ron R1 - адрес текущей ячейки области сохранения

*/

m("cflush");

 // инициализация адреса

 Q + z => Ron R1; e;

 Ron R1 .cshl 2 => Ron R1; e;

 OSI + Ron R1 => Ron R1; e;

 // главный цикл

m("cf-loop");

 Ron R1 + z => Ba; e;

 I(Bot;S) + z => Bd; e;

 write4;  Q + z -> Q; C1; e;

 blk0; Ron R1 + 4 => Ron R1; e;

 BotI + z => I(Bot;S); e;

 R2 + z => .a2 R2; C1; $0000 => .b2 skip; e;

 Q => BotI; cjmp(da31c, "cf-loop");

 Ron R1 - OSI => Ron R1; e;

 Ron R1 - RonLIM => .a2 skip; AluF => .b2 skip; e;

 cjmp (^da31c, "sovf");

 crtn(1);

Файл mkcomp.m

M("$EQ");

 I(Down;S1) - Is -> Q; e;

 Q + z; ron zero => .up Is; Alu Eq; e;

 Ret;

M("$EQI");

 z + Pip1 => R1; e;

 Is - R1 -> Q; e;

 Q + z; ron zero => .up Is; Alu Eq; e;

 Ret;

M("$NE");

 I(Down;S1) - Is -> Q; e;

 Q + z; ron zero => .up Is; Alu Ne; Ret;

M("$NEI");

 Z + Pip1 => R1; e;

 Is - R1 -> Q; e;

 Q + z; ron zero => .up Is; Alu Ne; Ret;

M("$LT");

 Is + z => RonPC; $0000 => .b2 skip; e;  

 I(Down;S1) - RonPC => .up Is; Alu Nl; e;

 1 .and Is -> Is; Ret;

M("$GT");

 z + I(Down;S1) -> Q; e;

 Is - Q => .up Is; Alu Nl; e;

 1 .and Is -> Is; Ret;

M("$LE");

 Is => .a2 skip; $0000 => .b2 skip; e;

 z + I(Down;S1) -> Q; e;

 Is - Q => .up Is; Alu Nl; e;

 1 .andnot Is -> Is; Ret;

//M("$GE");

M("*e46");

 Is + z => RonPC; $0000 => .b2 skip; e;

 I(Down;S1) - RonPC => .up Is; Alu Nl; e;

 1 .andnot Is -> Is; Ret;

M("$LTI");

 z + Pip1 => RonPC; e;

 RonPC => .a2 skip; $0000 => .b2 skip; e;   

 Cjs(Da7c, "ExtrB");

 Is - RonPC => .up Is; Alu Nl; e;

 1 .and Is -> Is; Ret;

M("*e4c");

 z + Pip1 => RonPC; e;

 RonPC => .a2 skip; $0000 => .b2 skip; e;   

 Cjs(Da7c, "ExtrB");

 z + Is -> Q; e;

 RonPC - Q => .up Is; Alu Nl; e;

 1 .and Is -> Is; Ret;

M("$LEI");

 z + Pip1 => RonPC; e;

 RonPC => .a2 skip; $0000 => .b2 skip; e;   

 Cjs(Da7c, "ExtrB");

 z + Is -> Q; e;

 RonPC - Q => .up Is; Alu Nl; e;

 1 .andnot Is -> Is; Ret;

M("*e4e");

 z + Pip1 => RonPC; e;

 RonPC => .a2 skip; $0000 => .b2 skip; e;   

 Cjs(Da7c, "ExtrB");

 Is - RonPC => .up Is; Alu Nl; e;

 1 .andnot Is -> Is; Ret;

M("$LTU");

 z + Is => R2; $0000 => .b2 skip; e;    

 I(Down); z + I(S1) => R1; e;

 js("ltur");

 z + R3 -> Is; Ret;

M("$LEU");

 z + Is => R1; $0000 => .b2 skip; e;    

 I(Down); z + I(S1) => R2; e;

 js("ltur");

 1 .andnot R3 -> Is; Ret;

M("$GTU");

 z + Is => R1; $0000 => .b2 skip; e;    

 I(Down); z + I(S1) => R2; e;

 js("ltur");

 z + R3 -> Is; Ret;

M("*e47");

 z + Is => R2; $0000 => .b2 skip; e;    

 I(Down); z + I(S1) => R1; e;

 js("ltur");

 1 .andnot R3 -> Is; Ret;

M("$LTUI");

 z + Pip1 -> R2; e;

 z + Is -> R1; e;

 js("ltur");

 z + R3 -> Is; Ret;

M("$LEUI");

 z + Pip1 -> R1; e;

 z + Is -> R2; e;

 js("ltur");

 1 .andnot R3 -> Is; Ret;

M("$GTUI");

 z + Pip1 -> R1; e;

 z + Is -> R2; e;

 js("ltur");

 z + R3 -> Is; Ret;

M("*e4f");

 z + Pip1 -> R2; e;

 z + Is -> R1; e;

 js("ltur");

 1 .andnot R3 -> Is; Ret;

M("ltur"); // вход: R1, R2 - операнды, выход: в R3 результат сравнения

 R1 => .a2 skip; $0000 => .b2 skip; e;   

 cjmp(Da31c, "-ltur");

 R2 => .a2 skip; $0000 => .b2 skip; e;   

 z + z => R3; C1; crtn(Da31c);

 R1 - R2 -> R1; e;

 R1 .cshl 1 => R1; e;

 1 .and R1 -> R3; crtn(1);

M("-ltur");

 R2 => .a2 skip; $0000 => .b2 skip; e;   

 z + z => R3; crtn(^Da31c);

 R1 - R2 -> R1; e;

 R1 .cshl 1 => R1; e;

 1 .and R1 -> R3; crtn(1);

M("ExtrB");

 RonPC .ornot Ron R9 => RonPC; crtn(1);

M("*ef9");

 z + Is -> R1; e;

 Is .cshl 1 => Is; cjmp(zc, "cmp1ret");

 1 .and Is -> Is; Ret;

 M("cmp1ret");

 z + z -> Is; C1; ret;

M("*efA");

 z + Is -> R1; e;

 Is .cshl 1 => Is; cjmp(zc, "cmp0ret");

 1 .andnot Is -> Is; Ret;

M("cmp0ret");

 z + z -> Is; ret;

M("*efB");

 Is .cshl 1 => Is; e;

 1 .andnot Is -> Is; Ret;

M("$BLT");

 z + Pip1 => R1; e;

 Is + z => RonPC; $0000 => .b2 skip; e;   

 I(Down;S1) - RonPC => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (Da0c, "JUMP8");

 Ret;

M("$BGT");

 z + Pip1 => R1; e;

 z + I(Down;S1) -> Q; e;

 Is - Q => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (Da0c, "JUMP8");

 Ret;

M("$BLE");

 z + Pip1 => R1; e;

 z + I(Down;S1) -> Q; e;

 Is - Q => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (^Da0c, "JUMP8");

 Ret;

M("$BGE");

 z + Pip1 => R1; e;

 Is + z => RonPC; $0000 => .b2 skip; e;   

 I(Down;S1) - RonPC => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;   

 I(Down;S1) => Is; cjmp (^Da0c, "JUMP8");

 Ret;

M("$BLTI");

 z + Pip1 => RonPC; e;

 RonPC => .a2 skip; $0000 => .b2 skip; e;   

 Cjs(Da7c, "ExtrB");

 z + Pip1 => R1; e;

 Is - RonPC => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (Da0c, "JUMP8");

 Ret;

M("$BGTI");

 z + Pip1 => RonPC; e;

 RonPC => .a2 skip; $0000 => .b2 skip; e;   

 Cjs(Da7c, "ExtrB");

 z + Pip1 => R1; e;

 z + Is -> Q; e;

 RonPC - Q => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1)=>Is; cjmp (Da0c, "JUMP8");

 Ret;

M("$BLEI");

 z + Pip1 => RonPC; e;

 RonPC => .a2 skip; $0000 => .b2 skip; e;   

 Cjs(Da7c, "ExtrB");

 z + Pip1 => R1; e;

 z + Is -> Q; e;

 RonPC - Q => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (^Da0c, "JUMP8");

 Ret;

M("$BGEI");

 z + Pip1 => RonPC; e;

 RonPC => .a2 skip; $0000 => .b2 skip; e;   

 Cjs(Da7c, "ExtrB");

 z + Pip1 => R1; e;

 Is - RonPC => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (^Da0c, "JUMP8");

 Ret;

M("$BLTU");

 z + Is => R2; $0000 => .b2 skip; e;    

 I(Down); z + I(S1) => R1; e;

 js("ltur");

 z + Pip1 => R1; e;

 R3 => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (Da0c, "JUMP8");

 Ret;

M("$BLEU");

 z + Is => R1; $0000 => .b2 skip; e;    

 I(Down); z + I(S1) => R2; e;

 js("ltur");

 z + Pip1 => R1; e;

 R3 => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (^Da0c, "JUMP8");

 Ret;

M("$BGTU");

 z + Is => R1; $0000 => .b2 skip; e;    

 I(Down); z + I(S1) => R2; e;

 js("ltur");

 z + Pip1 => R1; e;

 R3 => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (Da0c, "JUMP8");

 Ret;

M("$BGEU");

 z + Is => R2; $0000 => .b2 skip; e;    

 I(Down); z + I(S1) => R1; e;

 js("ltur");

 z + Pip1 => R1; e;

 R3 => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (^Da0c, "JUMP8");

 Ret;

M("$BLTUI");

 z + Pip1 => R2; e;

 z + Is => R1; e;

 js("ltur");

 z + Pip1 => R1; e;

 R3 => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (Da0c, "JUMP8");

 Ret;

M("$BLEUI");

 z + Pip1 => R1; e;

 z + Is => R2; e;

 js("ltur");

 z + Pip1 => R1; e;

 R3 => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (^Da0c, "JUMP8");

 Ret;

M("$BGTUI");

 z + Pip1 => R1; e;

 z + Is => R2; e;

 js("ltur");

 z + Pip1 => R1; e;

 R3 => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (Da0c, "JUMP8");

 Ret;

M("$BGEUI");

 z + Pip1 => R2; e;

 z + Is => R1; e;

 js("ltur");

 z + Pip1 => R1; e;

 R3 => .a2 skip; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (^Da0c, "JUMP8");

 Ret;

M("$BEQ");

 z + Pip1 => R1; e;

 I(Down;S1) - Is -> Q; e;

 Q + z; ron zero => .up Is; Alu Eq; e;

 1 .and Is; $0000 => .b2 skip; e;    

 I(Down;S1)=>Is; cjmp (^zc, "JUMP8");

 Ret;

M("$BEQI");

 Is - Pip1 -> Q; e;

 Q + z; ron zero => .up Is; Alu Eq; e;

 z + Pip1 => R1; e;

 1 .and Is; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; cjmp (^zc, "JUMP8");

 Ret;

M("$BNE");

 z + Pip1 => R1; e;

 I(Down; S1) - Is -> Q; e;

 Q + z; ron zero => .up Is; Alu Ne; e;

 1 .and Is; $0000 => .b2 skip; e;     

 I(Down;S1) => Is; cjmp (^zc, "JUMP8");

 Ret;

M("$BNEI");

 Is - Pip1 -> Q; e;

 Q + z; ron zero => .up Is; Alu Ne; e;

 z + Pip1 => R1; e;

 1 .and Is; $0000 => .b2 skip; e;    

 I(Down;S1) + z => Is; cjmp (^zc, "JUMP8");

 Ret;

M("$BLT0");

 z + Pip1 -> R1; e;

 Is .cshl 1 => Is; e;

 1 .and Is; e;

 I(Down;S1) => Is; cjmp (^zc, "JUMP8");

 Ret;

M("$BLE0");

 z + Pip1 -> R1; e;

 z + Is -> R2; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; e;

 z + R2; e;

 R2 .cshl 1 => R2; cjmp(zc, "JUMP8");

 1 .and R2 -> R2; $0000 => .b2 skip; e;   

 cjmp (^zc, "JUMP8");

 Ret;

M("$BGT0");

 z + Pip1 -> R1; e;

 z + Is -> R2; $0000 => .b2 skip; e;    

 I(Down;S1) => Is; e;

 z + R2; e;

 R2 .cshl 1 => R2; cjmp(zc, "bgt0end");

 1 .andnot R2 -> R2; $0000 => .b2 skip; e;   

 cjmp (^zc, "JUMP8");

M("bgt0end");

 Ret;

M("$BGE0");

 z + Pip1 -> R1; e;

 Is .cshl 1 => Is; e;

 1 .andnot Is -> Is; $0000 => .b2 skip; e;   

 I(Down;S1) => Is; cjmp (^zc, "JUMP8");

 Ret;

M("$LOOPP");

 Is + Pip1 => Is; e;

 Is - I(S1) => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;    

 z - Pip1 -> R1; cjmp (^Da0c, "LoopEnd");

 jmp("JUMP8");

M("$LOOPP1");

 Is + z => Is; C1; e;

 Is + z => RonPC; e;

 Is - I(S1) => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;    

 z - Pip1 -> R1; cjmp (^Da0c, "LoopEnd");

 jmp("JUMP8");

M("$LOOPM");

 Is - Pip1 => Is; e;

 Is + z => Ron R1; e;

 I(S1) - Ron R1 => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;    

 z - Pip1 -> R1; cjmp (^Da0c, "LoopEnd");

 jmp("JUMP8");

M("$LOOPM1");

 Is - z => Is; C0; e;

 Is + z => Ron R1; e;

 I(S1) - Ron R1 => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;    

 z - Pip1 -> R1; cjmp (^Da0c, "LoopEnd");

 jmp("JUMP8");

M("$LOOPP16");

 Is + Pip1 => Is; e;

 Is - I(S1) => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;    

 cjmp (Da0c, "$B16");

 z + Pip2; I(Down); e;

 z + I(Down;S1) -> Is; e;

 Ret;

M("$LOOPM16");

 Is - Pip1 => Is; e;

 Is + z => RonPC; e;

 I(S1) - RonPC => .up Is; Alu Nl; e;

 Is => .a2 skip; $0000 => .b2 skip; e;

 cjmp (Da0c, "$B16");

 z + Pip2; I(Down); e;

 z + I(Down;S1) -> Is; e;

 Ret;

M("LoopEnd");

 I(Down); $0000 => .b2 skip; e;

 z + I(Down;S1) -> Is; Ret;

Файл mkdev.m

// Команды работы с внешними устройствами

// Мнемоника команды: devrd

//M("devrd");

M("*f0b");

 // Верхние 3 бита адреса записываем в МОНы, сохранив их прежнее значение

 Is .cshl 8 => Is; e;

 push($20); rfst;

 z + $18 => Arb; e;

 Is .and $7 -> R1 => MonIO; e;

 Is .andnot $FF => Is; e;

 Is .cshl 24 => Is; e;

 // Производим обмен

 Is => Ba; e;

 ReadIO; e;

 blk1; e;

 Bd => Is; e;

 // Уходим на завершение

 jmp("dev_fin");

//----------------------------------------------------------------------------

// Мнемоника команды: devwr

//M("devwr");

M("*f0c");

 // Верхние 3 бита адреса записываем в МОНы

 I(S1) .cshl 8 => R1 => I(S1); e;

 push($20); rfst;

 z + $18 => Arb; e;

 R1 .and $7 -> R1 => MonIO; e;

 I(S1) .andnot $FF => I(S1); e;

 I(S1) .cshl 24 => I(S1); e;

 // Производим обмен

 I(Down;S1) => Ba; e;

 WriteIO; Is => Bd; e;

 blk0; e;

 // Подстраиваем стек и уходим на завершение

 I(Down;S1)=>Is;  jmp("dev_fin");

//----------------------------------------------------------------------------

// Мнемоника команды: devbr

// Чтение блока из устройства (области данных выравнены на 4 байта)