Дорогие посетители.Убедительно просим Вас Загружать имеющуюся у Вас информацию (Файлы образов дисков, Исходники, Книги и т.д.) касающуюся ПЭВМ с архитектурой PDP-11.
На
этой страничке мне хотелось бы
коротко рассказать об очень широко
распространенной в свое время ЭВМ
"Электроника-60" - имеются в виду
ВУМС, ДВК и прочие на ее базе. По
нынешним временам, конечно,
возможности этой "персоналки"
смешны, но тем не менее многое в ней
заслуживает внимания. Тем более что
это машина, на которой я учился
программировать :-)
Сразу
отмечу, что данная статья ни в коей
мере не претендует на полное и
абсолютно точное техническое
описание, да и вряд ли такое кому-то
нужно. Ну а если все-таки нужно -
отсылаю к великолепной по содержанию
и ужасной по оформлению полу-книге,
полу-брошюре "Центральный
процессор М2". Читалась она (для
начинающего) очень тяжело, но в ней
было ВСЕ. Абсолютно ВСЕ. Даже пример
схемы внешнего устройства.
Итак,
сперва смешное. Вот некоторые
выдержки из описания центрального
процессора М2, на основе которого и
были построены вышеуказанные ЭВМ.
Разрядность слова, бит
16
А
это - реальная распечатка моей
программы, которая мерила (или по
крайней мере пыталась мерить)
быстродействие процессора для
различных методов адресации.
Насколько я помню, это относилось
к ДВК-2
Объем логического
адресного пространства, К слов
32
Емкость резидентного ОЗУ,
К слов
4
Число команд
81
Быстродействие, оп/сек
250 000
Разрядность чисел с
плавающей запятой
32
Число БИС (больших
интегральных схем)
5
Размеры платы, мм
240 х 280
Построенный
на базе "Электроники-60"
вычислительный комплекс ВУМС имел
примерно такой вид:
Питание-
от 3-фазной сети 380В
Потребляемая
мощность
- не более 1750 Вт
Впрочем,
габариты его могли быть и
значительно уменьшены - системный
блок (3) и ГМД-70(2) поднимались выше,
дисплей (4) ставился в стойку, да и
принтер мог быть поменьше...
Ну
а теперь коротко о архитектуре -
преимущественно с точки зрения
программиста.
Системный
блок, на картинке - это (3) представлял
собой корзину, в которую вставлялись
платы - процессора и периферии. Плата
процессора всегда ставилась сверху,
потому что система прерываний в "Электронике-60"
отличалась от более привычной нам
теперь IBM-овской. Если совсем
примитивно - то линии запроса
прерывания (к процессору) и
предоставления прерывания (от
процессора) проходили по корзине,
скажем так, сверху вниз -
соответственно, наивысший приоритет
имела ближайшая к процессору плата. А
вектор прерывания процессору
сообщала сама плата периферии, так
что ситуации нехватки линий IRQ там
быть не могло - векторов было 256. Да,
еще - при обращении процессора к
какому-либо адресу - или ОЗУ, или
внешнего устройства - аппаратура
должна была сформировать сигнал "СИП"
(СИнхронизация Пассивного) -
отсутствие которого вызывало
прерывание "обращение к
несуществующей ячейке памяти". В
IBM-овской архитектуре процессор
просто ничего не заметит.
На
системном блоке (справа) были три
тумблера - питания, перевода в
шаговый режим и включения таймера.
Перевод в шаговый режим - по сути это
была зашитая в ПЗУ программа
монитора, если ее можно так назвать. С
ее помощью можно было просматривать
и изменять содержимое памяти и
регистров, проходить программу по
шагам, запускать тесты, загружаться и
так далее.
Для
программиста "Электроника-60"
представляла собой восемь 16-ти
разрядных регистров R0-R7, слово
состояния процессора, ОЗУ и регистры
внешних устройств, которые
находились в верхних 4 кБ адресного
пространства.
Регистры
R0-R5 были регистрами общего
назначения (РОН), R6 - указатель стека SP,
R7 - счетчик команд PC. Но в отличие от
привычных нам AX,BX... все регистры были
абсолютно равнозначны, то есть можно
было написать ADD #10, PC и получить JMP.
Хотя делать такого не
рекомендовалось. Кстати, в
двухоперандных командах и приемник и
источник могли быть в памяти - в
произошедших от 8086 процессорах
такого нет до сих пор, если не считать
достаточно своеобразные "строковые"
команды.
К
ячейкам памяти можно было
адресоваться как к байтам, так и к
словам. . К регистрам тоже можно было
адресоваться как к байту, но только к
младшему. А вот команды процессора
всегда были двухбайтными.
Формат
безоперандной команды:
15
14
13
12
11
10
09
08
07
06
05
04
03
02
01
00
Код команды
однооперандной:
15
14
13
12
11
10
09
08
07
06
05
04
03
02
01
00
Код команды
адресация
РОН
двухоперандной(src-источник,
dst-приемник):
15
14
13
12
11
10
09
08
07
06
05
04
03
02
01
00
Код команды
адресация
src
РОН
адресация
dst
РОН
Из
вышеуказанного сразу видно, почему
на этих машинах применялась не
шестнадцатеричная, а восьмеричная
система представления данных - одной
цифрой кодировались три разряда, и
все получалось весьма наглядно. А
наглядность была очень нужна, когда
надо было править код ручками.
Но
самое достойное описания в том
процессоре - это методы адресации.
Надеюсь, ничего не напутаю за
давностью...
Методы
адресации процессора М2
Двоичный
код адресации
Название
Описание
Пример
000
Регистровый
Операнд находится в
регистре
mov R0,R4
010
Автоинкрементный
В регистре находится
адрес операнда, после
выполнения регистр
увеличивается на 1(байтовая
операция) или 2(словная)
mov R0,(R4)+
100
Автодекрементный
То же, но регистр
уменьшается ДО выполнения
команды
mov R0,-(R4)
110
Индексный
Адресом операнда
является сумма регистра и
следующего за командой слова
mov R0, 10(R4)
001
Косвенно- регистровый
Адрес операнда в
регистре
mov R0,(R4)
или
mov R0,@R4
011
Косвенно-
автоинкрементный
В регистре находится
адрес адреса (!), после
выполнения команды регистр
инкрементируется аналогично
коду 010
mov R0,@(R4)+
101
Косвенно-
автодекрементный
Аналогично коду 100
mov R0,@-(R4)
111
Косвенная индексация
Адресом адреса
операнда является сумма
регистра и следующего за
командой слова
mov R0,@10(R4)
Следующие
режимы адресации можно
выделить как специальные,
поскольку в качестве регистра в
них используется R7 (PC),
указывающий на адрес
инструкции, подлежащей
исполнению
010 111 (278)
непосредственная
операнд следует за
словом инструкции. По сути, это
автоинкрементная адресация с иcпользованием
PC
mov #1,R0
011 111 (378)
абсолютная
слово, следующее за
словом команды, является
абсолютным адресом операнда
mov R0,@#1000
110 111 (678)
относительная
адресом операнда
является сумма PC и смещения в
следующем за командой слове.
Код получается перемещаемый!
mov R0,ADRES
111 111 (778)
Относительно-
косвенная
Адрес адреса операнда
вычисляется как сумма PC и
следующего за командой слова
mov R0,@ADRES
Система команд
процессора М2
(B)
- команда может выполняться со словом
или байтом, определяется старшим
битом команды. В графе "Код" он
обозначен звездочкой *
R
- регистр общего назначения
SS
- 6 разрядов, определяющих источник
DD
- 6 разрядов, определяющих приемник
XXX
- 8 разрядов смещения в инструкциях
ветвления
ССП
- слово состояния процессора
NN
- 6-ти битное смещение
Мнемоника
Код (8-чный)
Наименование
HALT
000000
Останов - переход в режим
клавиатурного монитора
WAIT
000001
Ожидание прерывания
RTI
000002
Возврат из прерывания
BPT
000003
Прерывание отладки (точка
останова)
IOT
000004
Прерывание для ввода-вывода
RESET
000005
Сброс (формирование сигнала "сброс"
на шине)
RTT
000006
Возврат из прерывания с
установленным T-разрядом ССП -
это использовалось вроде в
отладчиках
JMP
0001DD
Безусловный переход
RTS
00020R
Возврат из подпрограммы
JSR
004RDD
Обращение к подпрограмме.
Работала очень хитро, см.
описание ниже!
EMT
104000- 104377
Командное прерывание
TRAP
104400- 104777
Командное прерывание
NOP
000240
Нет операции. На самом деле это
команда "очистить никакой
разряд слова состояния
процессора", см. далее
CLC
000241
Очистка "С" разряда ССП (слова
состояния процессра)
CLV
000242
Очистка соответствующих
разрядов ССП. Вообще-то можно
очищать сразу несколько,
определяется четырьмя младшими
битами команды. А если никаких не
очищать - получится NOP
CLZ
000244
CLN
000250
SEC
000261
Абсолютно аналогично
командам очистки
SEV
000262
SEZ
000264
SEN
000270
SWAB
0003DD
Перестановка младшего и
старшего байт
CLR(B)
*050DD
Очистка
COM(B)
*051DD
Инвертирование
INC(B)
*052DD
Инкремент
DEC(B)
*053DD
Декремент
NEG(B)
*054DD
Изменение знака
ADC(B)
*055DD
Прибавление переноса
SBC(B)
*056DD
Вычитание переноса
TST(B)
*057DD
Проверка - по сути, установка
признаков по содержимому DD. Дело
в том, что команда пересылки
изменяла признаки N и Z ССП! Что
вообще-то странно.
ROR(B)
*060DD
Циклический сдвиг вправо через
C разряд
ROL(B)
*061DD
То же влево
ASR(B)
*062DD
Арифметический сдвиг вправо (деление
на 2)
ASL(B)
*063DD
То же влево (умножение на 2)
MARK
0064NN
Восстановление SP - никогда эту
команду не использовал. Что-то
мудреное :-)
SXT
0067DD
Расширение знака
MTPS
1064SS
Запись ССП / Чтение ССП.
Учитывая изменение ССП командой
пересылки, этими командами
приходилось пользоваться часто
MFPS
1067DD
MOV(B)
*1SSDD
Пересылка. Кроме изменения ССП,
была еще одна тонкость -
пересылка байта в регистр
вызывала автоматическое
расширение знака
CMP(B)
*2SSDD
Сравнение
BIT(B)
*3SSDD
Проверка разрядов (логическое И,
не изменяя операндов)
BIC(B)
*4SSDD
Очистка бит
BIS(B)
*5SSDD
Установка бит
XOR
074RDD
Исключающее ИЛИ
ADD
06SSDD
Сложение (работает только со
словами, как и вычитание)
SUB
16SSDD
Вычитание
BR
0004XXX
Ветвление безусловное. Во всех
инструкциях ветвления младший
байт команды представляет число
со знаком, определяющее
расстояние передачи управления.
BNE
0010XXX
Ветвление, если не равно
BEQ
0014XXX
Ветвление, если равно
BGE
0020XXX
Ветвление, если больше или
равно
BLT
0024XXX
Ветвление, если меньше
BGT
0030XXX
Ветвление, если больше
BLE
0034XXX
Ветвление, если меньше или
равно
BPL
1000XXX
Ветвление, если плюс
BMI
1004XXX
Ветвление, если минус
BHI
1010XXX
Ветвление, если больше (беззнаковое)
BLOS
1014XXX
Ветвление, если меньше или
равно (беззнаковое)
BVC
1020XXX
Ветвление, если нет
переполнения
BVS
1024XXX
Ветвление, если переполнение
BHIS
1030XXX
Ветвление, если больше или
равно (беззнаковое)
BLO
1034XXX
Ветвление, если меньше (беззнаковое)
SOB
077RNN
Декремент регистра и ветвление,
если не 0. NN - 6 разрядов, ветвление
всегда назад
MUL
070RSS
Целочисленное умножение. Если
регистр R четный, то в R младшая
часть результата, а в R+1 старшая.
Если R нечетный - только младшая
часть результата
DIV
071RSS
Целочисленное деление, регистр
R обязательно четный. В R+1 старшая
часть делимого и остаток после
операции.
ASH
072RSS
Арифметический сдвиг на N
разрядов (N - 5 разрядов + знак)
ASHC
073RSS
Арифметический сдвиг на N
разрядов двойного слова
FADD
07500R
Операции с плавающей
запятой. Насколько помнится, R
указывал на блок из 4-х слов, в
котором размещались два числа в
формате с плавающей запятой.
Точнее не помню. Да, команды,
начиная с ASH, были не во всех - в
процессоре M1 их точно не было.
FSUB
07501R
FMUL
07502R
FDIV
07503R
Вроде
все... Надеюсь, ничего не забыл. И
хотелось бы еще остановиться на
команде перехода на подпрограмму,
поскольку она была, скажем так, не
совсем обычна...
JSR Rn, адрес
По
этой команде:
1) содержимое Rn заносилось в стек
2) в регистр Rn заносился адрес
возврата (следующая команда после JSR)
3) адрес перехода заносился в PC
Так
что привычный CALL (JSR PC) являлся по сути
частным случаем. Если же учесть, что
адрес перехода мог задаваться любым
методом адресации, то извратиться
можно было как угодно. Например,
одной командой очистить все ОЗУ
машины! В стек заносился адрес верха
памяти+2, в нулевой адрес памяти
заносилось 004016 (JSR R0,@SP), в регистр R0
заносился 0 и "программа"
запускалась.
R0
записывался в стек, то есть в верхнюю
ячейку памяти, а в PC заносился адрес,
взятый из стека, то есть тот же ноль и
команда выполнялась снова. Стек
заполнялся нулями до тех пор, пока не
доходил до нулевого адреса, тем самым
записывая команду HALT и делая переход
на нее же. Выполнение программы на
этом останавливалось.
Или,
например, такая команда:
JSR PC,@(SP)+
Она
обеспечивает передачу управления на
адрес из вершины стека, оставив там
же свой адрес возврата, что позволяет
двум подпрограммам передавать
управление друг другу в любом месте!
Для этого нужно только занести в стек
адрес начала одной и передать
управление другой. И можно делать
параллельные процессы :-)