Исследование ИМС с помощью БК-0010.01

На некоторых специальностях Хабаровскою техникума железнодорожного транспорта изучается предмет «Основы вычислительной и микропроцессорной техники». Чтобы досконально усвоить логику работы ИМС, необходима отработка принципов их работы на макетах-тренажёрах.

Традиционный макет-тренажёр стандартен: это блок питания, индикаторы-светодиоды, элементы коммутации, генераторы, осциллограф. Изготовить такой макет трудно и дорого. Мы решили идти нетрадиционным путём.

Сначала разработали программы, позволяющие демонстрировать работу логических элементов И, ИЛИ, НЕ, ИЛИ-НЕ, И-НЕ. При изменении уровней входных сигналов заполняется таблица истинности, одновременно на экране вычерчивается временная диаграмма. Уязвимость способа в том, что нет навыка практической работы собственно с ИМС.

Освоив КУВТ-86, мы нашли иное решение этой задачи. Поясним на примере исследования ИМС счётчиков-делителей К155ИЕ2, ИЕ4, ИЕ5. Выполняется макет с коммутационными гнёздами и набором шаблонов, на которых изображены условные графические обозначения указанных ИМС (принципиальная схема - рис. 1).

Рис. 1

На макет с помощью разъёма можно установить любую ИМС. Питание ИМС обеспечивается от БК-0010. Управление работой ИМС осуществляется программно: микро-ЭВМ через порт ввода-вывода подаёт запускающие импульсы и анализирует состояние триггеров счётчика. Работа с программой сводится к нажатию клавиши ПРОБЕЛ, что имитирует подачу входного импульса и приводит к заполнению очередной строки таблицы истинности. Вид таблицы истинности зависит от того, какая коммутация произведена шнуровыми парами на макете (можно получить различные коэффициенты счета ИМС). При желании можно получить твёрдую копию таблицы. Пример - на рис. 2.

Таблица состояний

Номер импульса

Q1

Q2

Q3

Q4

0

0

0

0

0

1

1

0

0

0

2

0

1

0

0

3

1

1

0

0

4

0

0

1

0

5

1

0

1

0

6

0

1

1

0

7

1

1

1

0

8

0

0

0

1

9

1

0

0

1

10

0

1

0

1

11

1

1

0

1

12

0

0

1

1

13

1

0

1

1

14

0

1

1

1

15

1

1

1

1

16

0

0

0

0

Рис. 2

 

После заполнения таблицы истинности на экране строится временная диаграмма с требуемым коэффициентом пересчёта. Пример - на рис. 3.

 

Рис. 3

Перед началом работы с тренажёром учащемуся даётся задание получить для указанной ИМС временные диаграммы при нескольких коэффициентах деления.

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

Л. ПОПОВ, А. КОНДРАТЕНКО


 

Самомодифицирующиеся программы

  1. Полезными являются только четыре режима адресации, использующие программный счётчик (PC) в качестве регистра, а именно: 27 (непосредственный), 37 (абсолютный), 67 (относительный), 77 (косвенно-относительный ).
  2. После изменения программы требуется её перекомпиляция.
  3. Доступ к ячейкам, содержащим команды, должен быть разрешён только по чтению.

Эти и другие незыблемые правила работы в системе PDP-11, в качестве аналога которой можно рассматривать БК-0010, на самом деле являются достаточно спорными. Их нарушение даёт порой новые ценные возможности.

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

Регистровый (0) и косвенно-регистровый (1) режимы достаточно тривиальны.

Автоинкрементный (2) и автодекрементный (4) позволяют работать с массивами данных: чисел, кодов символов и т.д. Для этого нужно записать в один из регистров (Rk) адрес первого элемента массива (или следующего за последним) и в цикле обработать весь массив, обращаясь к элементу (Rk)+ или -(Rk).

Косвенно-автоинкрементный (3) и косвенно-автодекрементный (5) режимы позволяют работать с массивами адресов. Обработка массива аналогична предыдущему, а вот что такое массив адресов, разберём подробнее.

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

Что касается индексного (6) и косвенно-индексного (7) режимов, они позволяют обращаться к элементу массива данных (или адресов) по его номеру, если адрес начального элемента записать в регистр, а номер (для слов - удвоенный номер) - в ячейку для индекса. Отметим, что индекс (номер) записывается в отдельную ячейку, следующую за командой. К этому очень важному замечанию мы ещё вернёмся.

Непосредственный (27) режим позволяет записывать значение в ячейку, следующую за командой (например, для начального присваивания). Абсолютный (37) режим задаёт адрес для обработки, например, адрес регистра внешнего устройства.

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

Из оставшихся четырёх режимов остановимся подробно на 07 и 17 (47 и 57 действительно бесполезны).

Режим 07 рассмотрим на примере команд MOV и ADD. Если PC используется в качестве источника, то, например, команда MOV PC,DD (DD - приёмник) позволит запомнить адрес следующей ячейки в приёмнике. Это полезно при работе с подпрограммами, но команда JSR более эффективна. Команда ADD PC,DD и вовсе бесполезна. Если же PC - приёмник, то получим следующее. MOV SS,PC (SS - источник) приведёт к замене значения счётчика команд на значение источника, что равносильно безусловному переходу по абсолютному адресу. ADD SS,PC увеличит значение PC на значение источника, т.е. источник сыграет роль смещения аналогично командам BR, BEQ и т.д. Но здесь смещение не ограничивается одним байтом, что делает эту команду полезной в случаях, когда большое смещение не позволяет использовать команды BR, BEQ и др. Пусть нужно написать команду «если равно 0, то на 530(8) слов». Так как 530(8)>377(8), то BEQ использовать нельзя. Придётся действовать так:

        BNE     А            001002
        ADD     #1260,PC     012707
                             001260
А:      продолжение          ......

Замечание: 1260(8)=2*530(8). Смещение задаётся в байтах.

Таким образом, адресация 07 не так уж бесполезна.

Займёмся теперь адресацией 17, ради которой и написана статья.

Рассмотрим команду MOV (PC),DD. При её выполнении процессор:

Вот тут и возникает противоречие: содержимое ячейки должно быть, с одной стороны, значением, а с другой - командой. Трудно не согласиться с Т.С. Фрэнком, когда он в своей книге «PDP-11. Архитектура и программирование», отказав адресации 17 в практичности, переходит к адресации 27, при которой после прочтения значения PC снова увеличивается на 2 и указывает на следующую ячейку, уже с командой.

Зато случай MOV SS,(PC) предоставляет новые возможности, на которые не обратил внимания даже Т.С. Фрэнк. Проследим за выполнением этой команды:

Сразу возникают вопросы: зачем записывать команду в ячейку перед её выполнением, затратив при этом ещё команду, если можно было записать её туда в процессе создания программы? Как быть с той информацией, которая была в ячейке ранее? Где гарантия, что значением источника будет код нужной команды? Что, кроме неприятностей, принесёт изменение команд программы в процессе выполнения?

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

Простой пример. Пусть в источнике используется автоинкрементная адресация с регистром Rk ; тогда команда MOV (Rk)+,(PC) при каждом проходе цикла запишет в следующую ячейку очередной элемент массива, начальный адрес которого предварительно был записан в Rk. Этот массив логично назвать массивом команд, так как очередной его элемент будет выполняться как команда при очередном проходе цикла. Таким образом, этот приём позволяет использовать циклы с меняющимися командами.

Пример более сложный. В компьютере БК-0010 используются 15 различных режимов работы дисплея. С помощью команды ЕМТ 34 можно определить ССД (слово состояния дисплея), в котором отражены текущие режимы. Поскольку для каждой программы нужны свои режимы, требуется установить их.

Допустим, необходимо установить режимы (если они сброшены) 32 символа в строке (0-й бит), русский регистр (3-й бит), подчёркивание символа (4-й бит), гашение курсора (14-й бит); сбросить режимы (если они установлены) инверсия фона (1-й бит), расширенная память (2-й бит), инверсия символа (5-й бит), индикация СУ (6-й бит), блокировка редактирования (7-й бит), ГРАФ (8-й бит); не изменять остальные режимы (несущественные).

Алгоритм достаточно прост: проверяем наличие (отсутствие) существенного режима и, если нужно сбросить (установить) его, передаём монитору код изменения данного режима с помощью команды ЕМТ 16. Реализовать его можно разными способами:

Покажем решение третьим способом.

        EMT     34          104034  ;SSD в R0
        MOV     R0,R1       010001  ;R0 в R1
        MOV     #1,R2       012702  ;Маска в R2
                            000001  ;Начальная
                ;                    маска = 1
        MOV     #AKOD,R3    012703  ;
                            AKOD    ;Адрес
                ; массива кодов смены режима
        MOV     #АКОМ,R4    012704  ;
                            АКОМ    ;Адрес
                ;           массива команд
        MOV     #17,R5      012705  ;
                            000017  ;К-во
                ;           повторений цикла
        ; начало цикла              ;
A:      MOVB    (R3)+,R0    112300  ;Очередной
                ; код изменения режима в R0
        MOV     (R4)+,(PC)  012417  ;Очередную
                ; команду в следующую ячейку
        NOP                 000240  ;..команда..
        BIT     R2,R1       010201  ;Проверка
                ;           очередного режима
        BEQ     В           001401  ;Проверка
                ;           на изменение режима
        ЕМТ     16          104016  ;Изменение
                ;           очередного режима
В:      ASL     R2          006302  ;Очередная
                ;           маска
        SOB     R5,A        077510  ;
        ; конец цикла
 
Массив кодов
 Байты  Слова
235 233 116633
016 214 007214
234 237 116237
204 202 102202
226 225 113225
000 227 000227
000 000 000000
000 232 000232
 
Массив команд
XOR R2,R1   074201
NOP         000240
NOP         000240
XOR R2,R1   074201
XOR R2,R1   074201
NOP         000240
NOP         000240
NOP         000240
NOP         000240
BR  В       000403
BR  В       000403
BR  В       000403
BR  В       000403
BR  В       000403
XOR R2,R1   074201

Рассмотрим работу программы с массивом команд. В нём только три различные команды; их порядок зависит лишь от того, какие режимы нам нужны, и может быть произвольным. Команда NOP соответствует случаю, когда режим не нужен: последующие команды сбросят данный режим, если он установлен (ЕМТ 16), и не будут изменять, если сброшен (BEQ В). Команда XOR R2,R1 (случай нужного режима) изменяет в R1 значение очередного бита на противоположное (R2 - текущая маска), в результате чего последующие команды будут действовать наоборот: установят данный режим, если сброшен (ЕМТ 16), иначе оставят (BEQ В). В случае несущественных режимов используется команда BR В, которая позволяет сразу перейти к следующей маске и следующему режиму.

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

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

Пример 1.

        MOV     #ADR,R1     012701
                            ADR     ;Начальный
                ;               адрес массива
A:      ..........................
                                    ;Расчет
                ;                   индекса
        MOV     SS,B        01SS67  ;3апись
                ;                   индекса
                            ......  ;Смещение
        ADD     0(R1),DD    0667DD  ;Работа
                ;   с конкретным  элементом
                ;                   массива
В:                          000000  ;Индекс
                ;       (меняется при записи)
        ..........................
        BEQ     А           ......  ;Варианты:
                ;                   BNE,SOB,...

Пример 2. Пусть при каждом проходе цикла подставляются команды разной длины:

        MOV     А, В        016767
                            ......  ;Смещение
                ;                       к А
                            ......  ;Смещение
                ;                       к B
        MOV     @#177662,R4 013704  ;Чтение
                            177662  ;кода из
                ; регистра данных клавиатуры
        ADD     R5,R2       060502
        NOP                 000240

Решение.

        MOV     #ADR,R1     012701
                            ADR     ;Начальный
                ;           адрес массива команд
А:      ..........................  ;Начало
                ;                   цикла
        MOV     (R1)+,B     012167
                            ......  ;Смещение
                ;                   к В
        MOV     (R1)+,C     012167
                            ......  ;Смешение
                ;                   к C
        MOV     (R1)+,D     012167
                            ......  ;Смещение
                ;                   к D
В:                          000000  ;Три ячейки
С:                          000000  ;для под-
D:                          000000  ;становки
                ;                    команды
        BЕQ     А                   ;Варианты:
                ;                   BNE, SOB, ...
        Массив команд (цифровые метки указывают
        номера команд и в программе не нужны)
1:      MOV     А,В         016767
                            ......  ; Смещение
                ;                   к А
                            ......  ; Смещение
                ;                   к B
2:      MOV     @#177662,R4 013704  ;Чтение
                            177662  ;кода из
                ; регистра данных клавиатуры
        NOP                 000240
3:      ADD     R5,R2       060502
        NOP                 000240  ;Вариант:
                ;                   BR+1 000401
        NOP                 000240
4:      NOP                 000240  ;Вариант:
                ;                   BR+2 000402
        NOP                 000240
        NOP                 000240
5:      ..........................  ;Далее
                ;                   аналогично

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

Ю. ГИМАТОВ


 

Обработка прерываний по клавише СТОП средствами Бейсика

Изменение действия клавиши СТОП - приём, широко используемый при программировании в машинных кодах. Реализация его проста: адрес обработки прерывания по клавише СТОП (он хранится в ячейке 4) заменяется на какой-либо другой (например, начала программы пользователя или её фрагмента).

Как оказалось, Бейсику тоже вполне по силам «приручить» клавишу СТОП. Теоретические предпосылки взяты из статьи А. и В. Авсеевых «Особенности транслятора с языка Бейсик для БК-0010-01» (ИНФО. 1990. № 2.), которым автор выражает огромную благодарность за их замечательную работу, и сводятся к следующему.

Исполняемая Бейсик-программа хранится в памяти БК в виде «шитого кода» - последовательности адресов подпрограмм ПЗУ, реализующих команды Бейсика, и необходимых для работы этих подпрограмм данных. Начальный адрес расположения «шитого кода» задаётся чётным числом, равным или превышающим на 1 хранящееся в ячейке 1026[*] (т.е. его можно определить как РЕЕК (1026%)+РЕЕК(1026%)MOD2%). Управление от одной подпрограммы к другой передаётся через регистр R4: в конце каждой подпрограммы ПЗУ стоит команда JMP @(R4)+, т.е. в R4 находится адрес, адреса следующей подпрограммы. Изменив содержимое R4 в процессе выполнения Бейсик-программы, мы тем самым изменим порядок её выполнения.

Пусть, например, надо, чтобы при нажатии на СТОП Бейсик-программа начинала работу с самого начала. Из сказанного ясно, что для этого следствием нажатия на клавишу СТОП должны быть засылка в R4 адреса начала «шитого кода» программы и выполнение команды JMP @(R4)+, что обеспечивается добавлением в начало программы четырех строк:

10 POKE 512%,5572% 'код команды MOV (PC)+,R4 
20 POKE 514%,PEEK(1026%)+PEEK(1026%)MOD2% 'адрес адреса начала
30 POKE 516%,92% 'код команды JMP @(R4)+
40 POKE 4%,512% 'новый адрес обработки прерывания

А если при нажатии на клавишу СТОП должен произойти переход не к началу программы, а к какому-то её фрагменту?

Оставим в начале программы те же четыре строки, слегка изменив строку 20:

20 POKE 514%,1000%

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

В качестве маркеров удобно использовать операторы END, STOP, ВЕЕР, CLS, CLOSE («шитый код» соответственно -9774, -9748, -8718, -8706, -6738).

Расположим после нашей программы строки, определяющие адрес маркера:

10000 FOR J%=1500%TO16382%ST2% 'просмотр памяти от 1500 до конца ОЗУ
10010 IF PEEK(J%)=-9774%TH?J% 'маркером выбран END 
10020 NEXT J%

Выполним их.

RUN 10000

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

Но это ещё не всё. Нехорошо оставлять программу, «засорённую» вспомогательными элементами, поэтому удалим все три маркера и строки 10000-10020, предварительно запомнив адрес первого из маркеров (меньшее из трёх последовательных чисел) и посмотрев содержимое ячейки 1026.

После удаления «мусора» произведём «утряску» программы командой REN и вновь посмотрим содержимое ячейки 1026. Там будет число меньше предыдущего. Их разность даст «поправку на удаление»; вычтя её из первого маркера, получим нужный адрес. Осталось занести его в строку 20 вместо числа 1000, вызвав её на редактирование командой .20.

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

Рассмотрим пример. Текст программы:

10 POKE 512%,5572% 
20 POKE 514%,1000%
30 POKE 516%,92%
40 POKE 4%,512%
50 CLS
60 ?"A";
70 J%=J%+1%
80 GOТO 60
81 END
82 END
83 END
90 CLS
100 ?"Выдано"J%"’А’"
110 РОКЕ 4%,-24420%
120 END
10000 FOR J%=1500%TO16382%ST2%
10010 IF PEEK(J%)=-9774%TH?J%
10020 NEXT J%

Найдём адрес фрагмента, записанного в строках 90-120:

RUN 10000
1798
1800
1802
1842
1900

Нужное нам число - 1798.

?РЕЕК(1026)
 1730
DEL 81-83
DEL 10000-
REN
?PEEK(1026)
 1676
?1798-(1730-1676)
 1744

Нашли адрес, помещаем его в строку 20:

.20
20 POKE 514%,1000%
20 POKE 514%,1744%

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

10 POKE 512%,5572%
20 POKE 514%,1744%
30 POKE 516%,92%
40 POKE 4%,512%
50 CLS
60 ?"A";
70 J%=J%+1%
80 GOTO 60
90 CLS
100 ?"Выдано"J%"'A'"
110 POKE 4%,-24420%
120 END

Д. ЯКОШВИЛИ

Москва



[*] Здесь и далее все числа даны в десятичной системе счисления.


 

Псевдопараллельное исполнение программ на БК-0010

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

Расскажем об этом методе подробнее.

Слово состояния процессора (PSW) БК-0010 имеет адрес 177776. Его младший байт выглядит так:

177776:

P

P

P

T

N

Z

V

C

 

Для нас сейчас важен бит Т. Обычно он равен 0, если же в нём записана единица, то после исполнения каждой команды происходит прерывание по вектору 14, т.е. выполняются следующие команды:

MOV @#177776,-(SP)
MOV PC,-(SP)
MOV @#14,PC
MOV @#16,@#177776

После этого можно совершить какие-то действия и возвратить управление основной программе командой RTT, которая выполняет следующие действия:

MOV (SP)+,PC
MOV (SP)+,@#177776

Исполнится следующая команда основной программы, после чего снова возникнет прерывание по вектору 14 и т.д.

Установку бита Т в 1 обычно используют для пошагового исполнения кодовых программ при отладке. Мы же используем этот приём для организации «параллельного» исполнения программ, например, так.

Поместим в ОЗУ N программ и N специальных мониторов, работающих следующим образом. В момент работы первой программы бит Т=1, @#14=<адрес начала первого монитора>. После исполнения одной команды первой программы произойдёт прерывание и управление перейдёт к первому монитору, который сохранит значения регистров R0-R5, PC и PSW, а затем активизирует данные, необходимые для исполнения второй программы: зашлёт в регистры процессора значения, нужные второй программе, в стек - соответствующие ей значения PC и PSW, а в @#14-адрес начала второго монитора. После этого выполняется команда RTT, возвращающая управление, но уже не первой, а второй программе, поскольку значение PC в стеке было подменено монитором.

Второй монитор аналогично сохраняет регистры второй программы, а восстанавливает регистры третьей и т. д, вплоть до N-го монитора, который сохраняет регистры своей программы, а восстанавливает регистры первой и засылает в @#14 адрес первого монитора.

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

Но быстродействие нужно всё же посчитать. Сравним «сольное» исполнение программы и «параллельное» вместе с другими N-1 программам. Пусть время выполнения любой команды равно t. Тогда в первом случае на одну команду тратится время t, а во втором - не менее tN+ktN, где k - число команд в мониторе. Следовательно, происходит замедление по крайней мере в N(k+1) раз.

В испытываемых мониторах было 18 команд, замедление при работе двух программ было в 38 раз, не считая времени на операции по прерыванию.

Чтобы ослабить этот эффект, можно выполнять из каждой программы не одну команду, а серию из S команд, в течение которой дополнительное время уходит лишь на приращение счётчика серии, проверку его и команду RТТ (обозначим число этих дополнительных команд k1). Теперь время исполнения S команд каждой из N программ равно N(S+k1)t+N(k+1)t (к k добавляется единица, потому что при передаче управления другому монитору надо снова выставить счётчик).

Итак, при исполнении S команд каждой из N программ по одной тратится время, равное tSN(k+1), а при исполнении сериями по S команд - tN(S+k1+k+1). В первом случае общее время превосходит полезное (tSN) в k+1 раз, во втором - в (S+k1+k+1)/S раз.

При k=18, k1=3, S=22 в первом случае превышение реального времени над полезным в 19 раз, во втором - в 2 раза.

Рассмотрим реализацию этого алгоритма на БК-0010.

        ; 10-Jan-91
        ; Монитор для параллельного исполнения
        ; двух программ
START:  MOV     #VEC,R1         ;Пусковая инициализация
        MOV     #5,R0
1:      MOV     #20,@(R1)+
        SOB     R0,1
        MOV     #100274,@#4     ;По стопу
        CLR     @#6
        MOV     #INT1,@#14      ;По Т-разряду
        CLR     @#16
        MOV     #20,-(SP)       ;ССП для 1-й программы
        MOV     #20,PSR2        ;ССП для 2-й программы
        MOV     #10000,-(SP)    ;Стартовый адрес
                                ;   для 1-й программы
        MOV     #17000,PC2      ;Стартовый адрес
                                ;   для 2-й программы
        RTT
 
VEC:    .#12.#22.#26.#32.#36
 
INT1:   DEC     COUNT           ;Прерывание 1-й
        BNE     1               ;   программы
        MOV     #30,COUNT
        MOV     (SP)+,PC1
        MOV     (SP)+,PSR1
        MOV     R0,R01
        MOV     R1,R11
        MOV     R2,R21
        MOV     R3,R31
        MOV     R4,R41
        MOV     R5,R51
        MOV     R02,R0
        MOV     R12,R1
        MOV     R22,R2
        MOV     R32,R3
        MOV     R42,R4
        MOV     R52,R5
        MOV     PSR2,-(SP)
        MOV     PC2,-(SP)
        MOV     #INT2,@#14
1:      RTT
 
INT2:   DEC     COUNT           ;Прерывание 2-й
        BNE     1               ;   программы
        MOV     #30,COUNT
        MOV     (SP)+ ,PC2
        MOV     (SP)+,PSR2
        MOV     R0,R02
        MOV     R1,R12
        MOV     R2,R22
        MOV     R3,R32
        MOV     R4,R42
        MOV     R5,R52
        MOV     R01,R0
        MOV     R11,R1
        MOV     R21,R2
        MOV     R31,R3
        MOV     R41,R4
        MOV     R51,R5
        MOV     PSR1,-(SP)
        MOV     PC1,-(SP)
        MOV     #INT1,@#14
1:      RTT
 
PC1:    .#0                     ;Состояние 1-й
PSR1:   .#0                     ;   программы
R01:    .#0
R11:    .#0
R21:    .#0
R31:    .#0
R41:    .#0
R51:    .#0
РС2:    .#0                     ;Состояние 2-й
PSR2:   .#0                     ;   программы
R02:    .#0
R12:    .#0
R22:    .#0
R32:    .#0
R42:    .#0
R52:    .#0
COUNT:  .#30                    ;Размер серии команд
 
        END

Рассматривался случаи работы 2 программ, соответственно вспомогательная программа состояла из 3 частей: стартовой части и двух мониторов.

Стартовая часть (метка START) предназначена для установки векторов прерываний (вернее, их вторых слов) по Т-разряду, СТОПу, резервному коду, команде IOT, аварии питания, командам ЕМТ и TRAP. Кроме того, устанавливается холодный запуск монитора по нажатию СТОП и заносится адрес первого монитора (INT1) в @#14, а также заполняются начальные PC и PSW двух программ. Затем управление передаётся первой команде с одновременной установкой Т-бита с помощью команды RTT.

Программы исполняются сериями по 30 команд. Это реализуется с помощью ячейки COUNT. Мониторы INT1 и INT2 используют ячейки РС1-2, PSR1-2, R01 - R51, R02-R52 для хранения состояний программ 1 и 2. Программа написана на ассемблере МИКРО1103Б и не претендует на оптимальность - главным было продемонстрировать идеи метода.

Толчком к применению изложенного подхода было желание озвучивать программы, т.е. добиться параллельно исполнения программы, например, игры и программы, исполняющей мелодию. В экспериментах в качестве основной бралась программка, опрашивающая регистр 177716 и при выявлении нажатии клавиши печатающая код из @#177662. При S=64 и более (до 512) удавалось получить вполне приемлемое звучание, правда при уменьшении количества итераций в циклах типа SOB (они применяются в подпрограммах, генерируемых МЕЛОМАНом) в 2-10 раз.

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

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

В. БУЛИТКО


 

Подключение блока клавиатуры МС 7008.01 к БК

На прилавках магазинов «Электроника» недавно появились блоки клавиатуры «Электроника МС 7008.01», практически лишённые тех недостатков, которые столько лет досаждали пользователям БК. Новая клавиатура имеет очень лёгкий ход, избавлена от дребезга клавиш и с минимальными усилиями может быть встроена в уже имеющийся корпус ПЭВМ.

Технические характеристики клавиатуры:

мощность коммутируемого сигнала 10-2 ВА;

количество клавиш - 74;

наработка на отказ - 2x106 циклов;

усилие нажатия - 1,2 Н;

ход клавиши 3,5-4,5 мм;

частота нажатий на клавишу - 10 Гц.

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

Оставшийся на старой клавиатуре пьезодинамик следует осторожно выпаять и подсоединить к контактам 7 и 5 разъёма ХТ2 МС 7008.01.

Разъём XT1

МС 7008.01

Разъёмы шлейфов

Разъём XT2

МС 7008.01

Разъёмы шлейфов

Разъём XT3

МС 7008.01

Разъёмы шлейфов

1

XT2:15

1

-

1

-

2

XT1:1

2

XT2:9

2

XT1:15

3

XT1:2

3

XT2:10

3

XT2:11

4

XT1:3

4

XT2:14

4

XT2:1

3

XT1:5

5

XT2:8

5

XT1:14

4

XT1:6

6

XT2:4

6

XT1:13

7

XT1:11

7

XT2:5

 

 

8

XT1:7

8

XT2:2

 

 

9

XT1:9

9

XT2:3

 

 

10

XT1:10

10

XT2:7

 

 

11

XT1:4

11

XT2:6

 

 

12

XT1:8

12

-

 

 

 

Компактность и конструктивная простота МС 7008.01 позволяет использовать его в качестве дополнительной (выносной) клавиатуры; правда, при этом приходится решать две новые проблемы - где достать достаточно гибкий и лёгкий 27-жильный соединительный шлейф и как сделать корпус, но зато сколько удобств появляется потом!

И. ПАНЧЕНКОВ


 

Параллельные процессы на БК-0010

Нередко бывает желательно, чтобы во время выполнения программы играла музыка или, к примеру, мигал курсор. Этого можно добиться, вставив после каждых 100 команд команду TRAP с аргументом, соответствующим высоте звука для случая с мелодией, и написав соответствующую программу обработки прерывания по вектору 34.

Однако так невозможно добиться, например, мигания курсора во время выполнения системных ЕМТ-подпрограмм. Преодолеть это ограничение можно, используя прерывание по вектору 14 и внутренний таймер БК, подробно описанный в «ИНФО»1-90.

Вот пример подпрограммы, заставляющей мигать курсор, в том числе и во время выполнения ЕМТ 6 (во время остальных ЕМТ мигание прекращается).

;Текст программы пригоден для систем МИКРО10 и 
; старше. В случае использования более ранних 
; версий вводите только три первые буквы имен 
; меток и констант
PERIOD=177706 
DATA=177710 
UPR=177712
PUSK=160 
;*** Инициализатор ***
START:  MOV     #1000,@#PERIOD  ;Занесение периода в 
                                ;    регистр
        MOV     #PUSK,@#UPR     ;Запуск таймера
        MOV     #BEGIN,@#14     ;Занесение адреса
                                ;       п/п обработки
        BIS     #20,@#6         ;Установить Т-разряд
        BIS     #20,@#12        ; для всех прерываний
        BIS     #20,@#36
        MOV     @#30,SAVEMT     ;Сохранить старый
                                ;   вектор  ЕМТ
        MOV     #EMT,@#30       ;Активизировать
                                ;   ЕМТ-диспетчер
        BPT                     ;Выполнить п/п
                                ;   обработки
        JMP     @#100400        ;Выход в пусковой
                                ;   монитор
;*** П/п обработки прерывания *** 
BEGIN:  CMP     @#DATA,#600     ;Прошло ли время?
        BPL     RET             ;Нет - продолжить
                                ;   работу
        MOV     @#32,-(SP)      ;Сохранить ССП
        BIC     #20,@#32        ;Очистка Т-бита
        MOV     R0,-(SP)        ;Сохранить R0
        MOV     #232,R0         ;инвертировать курсор
        EMT     16
        MOV     (SP)+,R0        ;Восстановить R0
        MOV     (SP)+,@#32      ;Восстановить ССП
        MOV     #PUSK,@#UPR     ;Сброс и запуск
                                ;   таймера
RET:    BIS     #20,2(SP)       ;Установить Т-бит
        RTT                     ;Возврат из
                                ;   прерывания
;*** Диспетчер ЕМТ *** 
EMT:    MOV     R5,-(SP)        ;Сохранить R5
        MOV     2(SP),R5        ;(Адрес ЕМТ)+2 - в  R5
        MOV     -(R5),CMD       ;ЕМТ - в ячейку CMD
        MOV     (SP)+,R5        ;Восстановить R5
        MOV     SAVEMT,@#30     ;Восстановить
                                ;   вектор 30
        CMP     CMD,#104006     ;Это ЕМТ 6?
        BNE     CMD             ;Нет - выполнить
        BIS     #20,@#32        ;Разрешить прерывав.
                                ;   по Т-биту
CMD:    NOP                     ;Выполнить ЕМТ
        MOV     #ЕМТ,@#30       ;Адрес диспетчера
                                ;   - в 30
        BIC     #20,@#32        ;Запретить прерывая.
                                ;   по Т-биту
        RTT                     ;Возврат
 
SAVEMT: .#0                     ;Область для
                                ;сохранения вектора 30
        ЕND

Программа состоит из трёх частей: инициализатора, диспетчера ЕМТ и собственно подпрограммы обработки прерывания. Инициализатор выполняет начальный запуск таймера, сохранение вектора прерывания по ЕМТ, занесение адреса диспетчера ЕМТ в соответствующий вектор и установку Т-битов в ССП всех векторов прерываний. Диспетчер ЕМТ разрешает отладочное прерывание только на время работы ЕМТ 6 (это необходимо для нормальной работы с магнитофоном). Подпрограмма обработки прерывания по вектору 14 определяет, прошло ли необходимое время, и если да, то выдаёт команду на инвертирование курсора.

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

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

На основе системного таймера и прерывания по вектору 14 автором разработана программа МУЗОН, после компоновки с музыкальной подпрограммой редактора МЕЛОМАН 2 образующая перемещаемый блок исполнения мелодии параллельно выполнению основной программы. Существует версия МУЗОН: и с подсчётом числа выполненных команд.

Теоретически возможно распараллеливание до 5 процессов, но реально уже при 3 процессах работа значительно замедляется.

Автор благодарен Шишкину, автору игры KING’S VALLEY, а также авторам игры DIGGER за идею параллельного выполнения различных процессов.

Все заинтересовавшиеся данной темой, а также желающие получить МУЗОН могут написать по адресу: 241047, Брянск-47, а/я 109, брянский клуб пользователей БК.

Р. АСКЕРОВ

 

Performed by © gid, 2012-2022.