В этой части мы рассмотрим, как AGC организован с точки зрения программиста. Список литературы и источников приведён в конце первой части статьи. Материал этой части основан на материале книги [1].
Представление чисел в памяти AGC
AGC использует 15-битные слова, со знаком в 15-м разряде. Также имеется разряд чётности, который записывается и контролируется аппаратно и полностью прозрачно для программного обеспечения, при каждой операции чтения и записи в память.
Целые числа представлены в формате «дополнения 1». Он заключается в следующем:
Неотрицательные числа от 0 до 16387 представлены в виде кодов от 000 000 000 000 000 до 011 111 111 111 111 соответственно.
Отрицательные числа образуются путём инверсии положительных, т.е. -1 представлен как 011 111 111 111 111, и до -16387, представленным двоичным кодом 100 000 000 000 000.
Арифметические действия выполняются так:
2: 000 000 000 000 010
-5: 111 111 111 111 010
111 111 111 111 100 (= -3)
Сложение двух отрицательных чисел несколько более сложно.
Если мы будем складывать по обычным правилам, то ничего не получится:
-2: 111 111 111 111 101
-5: 111 111 111 111 010
111 111 111 110 111 (= -8)
Однако, можно заметить, что сложение старших разрядов генерирует бит переноса. Мы должны просто прибавить бит переноса, чтобы получить верный результат:
-2: 111 111 111 111 101
-5: 111 111 111 111 010
111 111 111 110 111 (= -8)
Carry 1
111 111 111 111 000 (= -7)
Также можно заметить, что в этой системе возможны положительный и отрицательный нуль, что создаёт дополнительные сложности для программистов, например, при сравнении результата операции с нулём.
Также может отслеживаться переполнение аккумулятора при арифметических действиях, о чём речь пойдёт немного ниже.
ACG поддерживает только целочисленную арифметику и может выполнять операции с вещественными числами аппаратно, но может делать это программно. AGC использует двоично-десятичное представление чисел длиной 28 бит (9 десятичных знаков), которое занимает две ячейки памяти, по 14 бит в каждой. Знаковые разряды тоже используются, причём младшее слово и старшее слово могут иметь разный знак! То есть, может быть число, представленное как, например, +5 * 10000 + -5*100 = 49500. Странно, но возможно.
Расстояния и скорости при расчётах представлены в метрической системе, но данные для экипажа отображаются в английской системе мер (футы и т.д).
Формат инструкции
Модель памяти
В предыдущей части уже упоминалось, что память компьютера делится на ОЗУ объёмом 2 Кслова и ПЗУ объёмом 36Кслов. Так как в инструкции для значения адреса отведено всего 12 бит, используется принцип разделения памяти на банки. Для указания текущего банка используется специальный регистр.
Для перехода на новый банк памяти используется команда «Transfer into New Bank» (TNB), которая выполняет следующее:
- Копирует текущий регистр банка («Bank») в регистр «Saved Bank»
- Копирует 12-битный адрес из ячейки памяти, следующей за командой TNB, в регистр «Return Address»
- Загружаем новый адрес банка в регистр «Bank», а в счётчик команд загружаем смещение, на которое указывает инструкция TNB.
Регистры
AGC имеет отображаемые на адресное пространство регистры. Они занимают первые 48 слов физической памяти.
Аккумулятор занимает адрес 08.
Аккумулятор используется в большинстве арифметических и логических операций (OR, AND и т.п.). Хотя AGC оперирует с 15-битными словами, аккумулятор имеет разрядность 16 бит, так как он хранит разряд переполнения. Когда данные загружаются в аккумулятор, они попадают в младшие биты, при этом бит 14 содержит знак числа. После выполнения арифметической операции, если не произошло переполнения, то бит 15 будет просто содержать копию знака, и этот разряд невидим для программиста. Назовём эти знаковые разряды как S1 и S2 соответственно. Если произошло переполнение, то S1 и S2 будут не равны между собой. И хотя бит S2 остаётся невидим для программиста, в AGC есть целых два способа установить состояние переполнения.
Во-первых, при возникновении переполнения автоматически запрещаются прерывания. Обработчик прерывания, если оно возникнет в этот момент, мог бы сбросить данный бит, что было бы очень нежелательно. Прерывания разрешаются только при очистке флага переполнения. Флаг сбрасывается только при очистке аккумулятора или при загрузке нового значения. Для проверки флага переполнения может использоваться команда Transfer to Storage (TS), которая сохраняет значение аккумулятора в память только в том случае, если переполнения не было, а если было переполнение в большую или меньшую сторону, значение в аккумуляторе заменяется на +1 или -1 соответственно. Команда TS также пропускает следующую инструкцию программы в том случае, если переполнение произошло. Предполагается, что программист напишет код, обрабатывающий переполнение, и разместит его через одну команду от TS, а сразу после TS вставит переход на инструкцию после обработчика переполнения.
Регистр L — адрес 000018
Регистр L также называется «the low order accumulator» и предназначен для расширения диапазона чисел, с которыми производятся операции. Также может использоваться для временного хранения переменных.
Регистр Q — адрес 000028
Регистр Q предназначен для сохранения адреса возврата. Регистр Q содержит 12-битный адрес, который в совокупности с текущим банком памяти даё полный адрес возврата из подпрограммы.
Регистр EBANK (Erasable Storage Bank) — адрес 000038
ОЗУ (называемая в AGC также «стираемой памятью»), содержит 2048 слов, разделённых на 8 банков по 256 слов. Адрес банка ОЗУ имеет 3 бита и содержится в регистре EBANK.
Регистр FBANK (Fixed Storage Bank) — адрес 000048
ПЗУ имеет банки по 1024 слова и содержит 36 банков. Регистр FBANK имеет 5 бит и позволяет адресовать 32 банка.
Fixed Extension Bit (Superbank Bit)
Используется для адресации последних 4Кслов ПЗУ.
Регистр BBANK (Both Banks Register) — адрес 000068
При передаче управления на другую программу нужно поменять оба регистра FBANK и EBANK одновременно. Регистр BBANK содержит оба адреса — номера банков ОЗУ и ПЗУ. Запись в него автоматически обновляет регистры FBANK и EBANK.
Регистр Z (The program counter) — 000058
Регистр Z является счётчиком программы, то есть он определяет адрес выполняемой в настоящее время команды. Он имеет разрядность 12 бит.
Регистр нуля (A source of zeros) — адрес 000078
Содержит константу 0.
Регистры обработчика прерывания — адреса 000088 — 000128
По этим адресам расположены соответственно регистры ZRUPT, BRUPT, ARUPT, LRUPT, QRUPT и BANKRUPT.
Регистры ZRUPT и BRUPT — автоматически сохраняют содержимое регистра Z (счётчик инструкций), и регистра B (внутренний регистр, который содержит адрес команды, которая будет выполняться следующей).
Регистры ARUPT, LRUPT, QRUPT и BANKRUPT служат для сохранения аккумулятора и регистров L, Q и BB. Эти регистры должны сохраняться вручную и восстанавливаться вручную до выполнения инструкции RESUME, служащей для возврата из прерывания.
В процессе обработки прерывания AGC запрещает прерывания до выполнения инструкции RESUME. Таким образом, обработчик прерывания сам по себе не может быть прерван.
Ранее уже упомигалось о том, что аккумулятор имеет разрядность 16 бит, и старший бит используется для детектирования переполнения и недоступен программно. Однако регистр ARUPT, в который сохраняется аккумулятор при прерывании, имеет 15 бит. Каждый раз, когда наступает состояние переполнения, прерывания запрещаются до тех пор, пока флаг переполнения не будет очищен.
Регистры ARUPT, LRUPT, QRUPT и BANKRUPT нельзя использовать вне обработчика прерывания. Физически они остаются доступными, но с точки зрения основной программы, их состояние меняется в произвольные моменты времени.
Регистры редактирования — адреса 000208 — 000238
Первые три регистра — это регистры сдвига: Cycle Right, Shift Right, Cycle Left, то есть циклический сдвиг вправо, сдвиг вправо и циклический сдвиг влево. Система команд AGC не имеет операций сдвига, и для того, чтобы произвести сдвиг числа на один разряд, его нужно записать в один из этих регистров и затем считать. При каждой записи производится сдвиг на один бит.
Регистр EDOP (EDit Interpretive OPcode) — четвёртый из регистров редактирования.
Команды интерпретатора, о котором пойдёт речь ниже, хранятся по две в одном слове и занимают по 7 бит каждая. Для чтения младшей команды достаточно операции AND с маской, но для старшей понадобится сдвиг на 7 бит. Регистр EDOP выполняет такой сдвиг за одну операцию.
Регистры редактирования нельзя использовать в обработчиках прерываний, и вот почему. Обычные регистры должны быть сохранены в начале обработчика, и восстановлены при выходе из него. Но регистры редактирования выполняют операции над данными при записи в них, и это приведёт к неверному функционированию прерываемой программы.
Таймеры и часы
Часы реального времени
AGC не использует календарное время, дни, месяцы и год. Вместо этого отсчёт производится от «нулевой» точки, которая начинается за несколько часов до старта. Часы отображаются на два слова в памяти, по адресам 000248 (T2), 000258 (T1). Слово T1 инкрементируется каждые 10 мс, слово T2 — приблизительно каждые 164 секунды, при переполнении слова T1.
Таймеры
000268 (T3) Wait list — инкремент каждые 10 мс., сдвинут относительно T4RUPT на 5 мс
000278 (T4) T4RUPT — инкремент каждые 10 мс.
000308 (T5) Автопилот — инкремент каждые 100 мс.
000318 (T6) часы высокого разрешения — инкремент каждые 1/1600 с = 0.625 мс.
Первый таймер, T3, нужен для работы переключателя задач (Wait list). Wait list — это список из очень коротких задач, каждая из которых занимает маленькое время, и может быть выполена непосредственно в обработчике прерывания. Список содержит до семи задач, каждая из которых запускается с определённым интервалом. Время выполнения задачи строго ограничено 4 мс. За это время компьютер успевает выполнить около 160 инструкций.
Таймер T4 запускает критические периодические задачи, имеющие интервал от 20 до 120 мс, включающие в себя обмен данными с DSKY, опрос переключателей на панелях управления кораблём и другие задачи.
Блок инерциальных измерений IMU (The Inertial Measurement Unit)
IMU — это гироскопически стабилизированная платформа с акселерометрами, которая служит для определения положения и ускорений корабля в пространстве.
Мы не будем описывать здесь принцип действия гироскопа, отметим только, что положение осей гироскопа измеряется устройством CDU (Coupling Data Unit). Это устройство вырабатывает импульсы при повороте осей гироскопа, производя 32768 импульсов на полный оборот, что соответствует разрешению 39,55 угловых секунды на импульс.
Также CDU передаёт в AGC положение осей секстанта и радара сближения. Так как секстант есть только в командном модуле, а радар — только в лунном модуле, они используют один и тот же порт AGC.
Также IMU имеет три маятниковых акселерометра (Pulsed Integrating Pendulous Accelerometers, PIPA). Но здесь есть небольшая тонкость. Несмотря на то, что лунный модуль и командный модуль имеют одинаковые IMU, их диапазоны измерения скорости различны. Дипазон скоростей IMU командного модуля составляет от 0 до 11000 м/c, а у лунного модуля — до 1700 м/с. Разрешение IMU командного модуля составляет 5,85 см/с, у лунного модуля — 1 см/с.
Счётчики CDUS (X, Y, Z, OPTIS, OPTT) и PIPAS (X, Y, Z)
Передача данных от CDU в AGC происходит следующим образом: импульсы от датчиков могут инкрементировать и декрементировать счётчики. Число в счётчике имеет знак, отображающий направление движения. Счётчики расположены по определённым адресам в памяти, и могут быть считаны программно. Всего используется 8 счётчиков, шесть из которых отображают скорости и углы, и два предназначены для отображения углового положения секстанта в командном модуле или радара сближения в лунном модуле.
Управление устройствами через счётчики
CDU работал в обоих направлениях, он, например, не только мог определять положение радара сближения, но и мог считывать содержимое регистра из памяти компьютера, и подавать на моторы привода радара напряжение, до тех пор, пока радар не будет установлен под требуемым углом.
Другие интерфейсы компьютера
На пульте лунного модуля имеется рукоятка (Attitude Controller Assembly, ACA) положение которой могло быть считано программно. Каждая ось этого контроллера посылала значения в переменные P_RHCCTR, Q_RHCCTR и R_RHCCTR.
Контроллер ACA
Контроллер ACA, внешний вид
Контроллер ACA установлен только в лунном модуле
INLINK (канал передачи телеметрии)
Устройство INLINK обеспечивает двустороннюю связь с Землёй, и служит для передачи телеметрической информации и приёма данных от центра управления полётами. Астронавты могут вводить необходимые для полёта данные через DSKY, но это процесс медленный и чреватый ошибками. Через регистр INLINK данные могут вводиться с Земли напрямую в компьютер.
Управление двигателями
На протяжении процесса посадки лунного модуля AGC непрерывно вычисляет необходимые значения силы тяги и подаёт на двигатели сигналы управления. В течение 12 минут, которые длится посадка, двигатель сжигает примерно половину топлива, и программа должна учитывать уменьшение массы. Тяга двигателя меняется от уровня 92,5%, что составляет 46700 Н, до 10% полной тяги. Но тяга выше 65% вызывает сильный износ камеры сгорания и сопла, поэтому программа AGC должна минимизировать время, когда двигатель работает в таком режиме.
Компьютер связан с двигателями посадочной платформы через Descent Engine Control Assembly (DECA). Управление происходит через регистр THRUST. Экипаж может корректировать значение тяги вручную через контроллер Thrust/Translational Hand Controller (TTHC).
Контроллер Thrust/Translational Hand Controller (TTHC).
Контроллер Thrust/Translational Hand Controller (TTHC). Внешний вид.
Рукоятка контроллера подключена к DECA напрямую, компьютер не видит введённых вручную значений.
Аналоговые приборы
Также используются аналоговые индикаторы, ALTM (analog displays: altimeter and rate meters), для индикации высоты над поверхности и скрости изменения высоты, которыми AGC управляет через регистр ALTM. Аналоговые индикаторы выполнены в виде вертикальных шкал (tapemeters).
Индикаторы высоты и вертикальной скорости
Адресация и банки памяти
Как уже упоминалось, AGC имеет два типа памяти, ОЗУ, называемое также «стираемой памятью» (erasable memory), и ПЗУ (fixed memory). Объём памяти составляет 38 Кслов, что не позволяет адресовать всю память непосредственно, так как длина адреса в командном слове составляет 12 бит.
Для разделения памяти на банки используются регистры банков EBANK и FBANK, задающие банк ОЗУ и ПЗУ соответственно. Это расширяет адресуемое пространство 32Кслов, и для дальнейшего расширения адресуемого пространства ПЗУ используется бит Fixed Extension Bit, который позволяет получить доступ к 36Кслов.
Банки ОЗУ
ОЗУ имеет объём 2Кслов, и делится на 8 банков по 256 слов.
Дешифрация адреса ОЗУ
Для адресации слова в банке ОЗУ нужно 8 бит. Ещё два бита нужно для определения типа банка: непереключаемый (unswithed) или переключаемый (swithed). За это отвечают биты 9 и 10 на рисунке выше (обратите внимание, что биты нумеруются с 1). Если эти биты содержат 00, 01 и 10, то регистр EBANK не используется, если 11 — используется, то содержимое EBANK объединяется с 8-битным адресом, записанным в командном слове, как показано на рисунке ниже. Если регистр EBANK не используется, то происходит обращение к первым трём банкам памяти, которые назваются немного вводящим в заблуждение термином «Fixed Erasable». Для обращения к ОЗУ биты 11 и 12 должны быть установлены в 0.
Дешифрация адреса ОЗУ при использовании регистра EBANK
ПЗУ
Для обращения к ПЗУ используется аналогичный подход. Биты 11 и 12 командного слова определяют, какие банки используются, если эти биты содержат 00, то используется ОЗУ, как показано в предыдущем разделе, если 10 или 11, то все 12 бит используются как адрес в ПЗУ, регистр FBANK при этом не используется, если 01, то используется адрес, состоящий из младших 10 бит командного слова и содержимого регистра FBANK.
Дешифрация адреса ПЗУ
Дешифрация адреса ПЗУ при использовании регистра FBANK
Общие банки
Важным побочным продуктом схемы разделения памяти на банки является возможность подключить в одно адресное пространство банки ПЗУ и ОЗУ, и использовать ОЗУ без необходимости переключать регистры банков. На рисунке поясняется, как работает такая схема.
Схема использования ОЗУ и ПЗУ в одном адресном пространстве
Память за пределами 32Кслов
Для доступа к памяти выше 32Кслов используется бит расширения ПЗУ, Fixed Extension Bit, он же бит супербанка (Superbank Bit). Бит супербанка находится в бите 7 канала ввода-вывода 7. Канал 7 отличается от остальных каналов тем, что поддерживает как чтение, так и запись. Разумеется, бит расширения ПЗУ необходимо сохранять как во время обработки прерываний, так и при переключении задач.
Передача управления между банками
Обратим внимание, в каком порядке расположены регистры FBANK, Z и BB в нижней памяти. Казалось бы, почему не объединить их в одном слове? Но так сделано специально, чтобы создать мехагизм передачи управления. При переключении на другой банк должны быть установлены новые значения FBANK и EBANK, либо BBANK. Однако, при этом возникает проблема. пусть, например, программа выполняется по адресу 010338 в банке ПЗУ 07, и нужно сделать переход на адрес 023718 в банке ПЗУ 13. При изменении регистра Z передаст управление по адресу 023718 в текущем банке, чего нам не нужно. Если мы сначала переключим текущий банк, возникнет похожая ситуация. Необходимо одновременное переключение регистра Z и банка памяти. Для этого используется инструкция DXCH, которая читает аккумулятор и регистр L, и обменивает их содержимое с двумя последовательными локациями в памяти. Таким образом, можно обменять аккумулятор и регистр L либо с парой FBANK, Z, либо с парой Z, BB. Эти варианты кодируются двумя мнемониками: Double Transfer Control Switching Both Banks (DTCB) и Double
Transfer Control Switching Fixed Bank (DTCF). Команда DTCB позволяет не только перейти по другому адресу, но и поменять банк ОЗУ, а команда DTCF передаёт управление, оставляя банк ОЗУ прежним. Возврат из функции производится так. Исходные значения Z и BBANK (или FBANK) оказываются записанными в аккумулятор и регистр L. Вызываемая функция должна сохранит эти значения, а затем проделать обратную операцию, обменяв значения с регистрами банков и Z.
Некоторые недостатки архитектуры AGC
В большинстве компьютерных архитектур присутствует указатель стека и/или индексные регистры (хотя бы один). Но не в AGC. Поддержка указателя стека потребовала бы дополнительных аппаратных затрат. Индексных регистров, которые позволяли бы организовывать доступ к структурам данных по адресу (указатель + смещение) тоже нет, но есть команда INDEX, которая устраняет необходимость в таком регистре. Также, хотя аппаратных индексных регистров нет, они эмулируются виртуальной машиной Interpreter, о которой речь пойдёт ниже.
Одной из особенностей AGC является использование многопоточной операционной системы реального времени. Для работы такой системы, как правило, необходим механизм блокировки разделяемых данных (мьютексы). Но в AGC такой механизм отсутствует, поэтому разработчики ПО должны тщательно проверять все случаи совместного доступа к данным из различных процессов, чтобы исключить возможность одновременного обращения к таким данным.
Прерывания
40008 Startup
Стартовый адрес после подачи питания AGC
40048 T6RUPT
TIME6 достиг 0. Таймер используется автопилотом.
40108 T5RUPT
TIME5 достиг переполнения. Таймер используется автопилотом.
40148 T3RUPT
TIME3 достиг переполнения. Используется планировщиком задач WAITLIST.
40208 T4RUPT
TIME4 достиг переполнения. Опрос и и обновление индикации DSKY
40248 KEYRUPT1
Нажате кнопки DSKY. Код нажатой клавиши с главного DSKY доступен в канале 15
40308 KEYRUPT2
Нажате кнопки второго DSKY. Код клавиши навигационного DSKY доступен в канале 16 (только в командном модуле)
40348 UPRUPT
Данные в регистре INLINK
Используется для DSKY
40408 DOWNRUPT
Регистр Downlink содержит данные. Используется для телеметрии AGC
40448 RADARUPT
Данные в регистре RNRAD. Данные от радара сближения
40508 RUPT10
LM P64
Система команд
Код операции, или Order Code, в терминах того времени, кодируется тремя битами, то есть возможно всего лишь восемь опкодов, чего явно недостаточно для развитой системы команд. Однако разработчики нашли выход. Некоторые коды расширены дополнительным двухбитовым полем, Q-Code.
Опкод 000 соответствует большому числу специальных операций, опкоды 011, 100 и 111 соответствуют одной операции каждый, Оставшиеся опкоды 001, 010, 101 и 110 используют Q-коды.
Формат команды с Q-кодом
Также для расширения числа возможных опкодов использовались и другие ухищрения. Некоторые инструкции не могут работать с ОЗУ, и указание ОЗУ в качестве адреса могло бы привести к неопределённому результату, но такие опкоды с адресами операнда в ОЗУ использовались для совершенно других операций. Например, команда передачи управления TC (transfer control), не может передать управление на ОЗУ, но если адрес указывает на ОЗУ, то такой опкод соответствует команде разрешения прерываний (Enable Interrupts).
Когда и этих опкодов не хватило, был использован следующий подход. Если мы совершаем переход командой ТС на адрес 000068, на самом деле никакого перехода не происходит, вместо этого следующий за командой ТС 000068 опкод интерпретируется как принадлежащий к совершенно другому набору инструкций. Конечно, такие инструкции требуют больше времени на выполнение, потому что процессор должен прочитать и декодировать два опкода, но эта проблема сглаживается тщательным распределением команд между двумя наборами инструкций. Часто используемые команды включены в основной набор инструкций, а оставшиеся в расширенный.
Основные инструкции
Всего AGC содержит 41 команду. Команды делятся на 6 групп:
- Арифметико-логические
- Передачи управления
- Перемещения данных
- Модификация инструкций
- Инструкции ввода-вывода
- Разное
Однако мы не будем описывать здесь все команды AGC. Интересующиеся могут обратиться к книге [1].
Связь с внешним миром: подсистема ввода-вывода
AGC не имеет жестких дисков или ленточных накопителей, и всё общение с внешним миром сводится к установке и чению битов в портах ввода-вывода. Периферийными устройствами AGC являются инерциальная платформа, двигатели, радар, DSKY и переключатели на панели управления. Скоростной обмен данными при этом не требуется, и укорость обмена не является существенным ограничивающим фактором.
Для ввода и вывода служат так называемые каналы. Запись и чтение канала происходит сходно с записью и чтением ячейки ОЗУ, но в отличте от ОЗУ, большинство каналов однонаправлены. Также есть порты-счётчики, которые служат для считывания положений осей IMU, радара и секстанта. Импульсы от датчиков углов инкрементируют и декрементируют счётчики, которые затем могут быть считаны AGC.
Периферийные устройства AGC
Инструкции ввода-вывода относятся к расширенному набору команд и требуют команды EXTEND перед опкодом. Команды ввода вывода имеют опкод 000, затем идёт трёхбитный PCode. Различные значения PCode используются только для наземгых тестов, по умолчанию PCode равен нулю. Остальные 9 бит командного слова — это номер канала. AGC, таким образом, может адресовать до 512 каналов, но на практике используются только 16. Большинство периферийных устройств связано не с полным 15-битным словом, а с отдельным битом в слове, то есть при операциях ввода-вывода требуются логические операции AND, OR и Exclusive OR. Такие операции могут быть объединены в одну операцию с операцией ввода-вывода. Для этого предназначены инструкции WOR (Write with OR), WAND (Write with AND), ROR (Read and OR) и RXOR (Read and XOR).
Инструкции ввода-вывода используют аккумулятор для чтения и сохранения данных. Но есть также регистр L (low-order accumulator), который может быть отображён на порт, тогда всё, что читается и записывается в него, будет автоматически попадать в порт. Это позволяет использовать для работы с портом обычные логические операции AND, OR и XOR.
Но не все операции ввода-вывода требуют чтения или записи только одного бита. Например, DSKY посылает коды клавиш длиной 5 бит. Нажатие кнопки на DSKY генерирует прерывание KEYRUPT, код при этом помещается во входной канал.
Ещё один пример, когда необходима передача большого количества данных через порт, это интерфейсы uplink и downlink, обеспечивающие связь с Землёй на скорости 51 кбит/c или 1900 бит/с (выбирается вручную экипажем).
Программное обеспечение
Программное обеспечение AGC основано на операционной системе реального времени Executive и виртуальной машине Interpreter. Их мы рассмотрим подробно в следующей части.
Автор: Владимир