КАЛЬКУЛЯТОР
Первая идея, которая приходит в голову читателю, получившему в руки ПМ-ЭВМ, т. е. вычислительную машину, — использовать ее для вычислений. Лишь потом, приобретая некоторый опыт, он поймет, что вычисления — весьма малый клочок обширного поля возможных применений микро-ЭВМ.
Система команд микропроцессора КР580ИК80А, использованного в ПМ-ЭВМ, позволяет непосредственно выполнять логические операции и операции сложения и вычитания над двоичными и двоично-кодированными десятичными числами, имеющими формат один или два байта. Тем не менее, используя тот факт, что микро-ЭВМ — программируемое устройство, имеющее память, можно реализовать практически неограниченное множество различных операций (арифметических, логических, функциональных и т. д.) над исходными данными, представленными в произвольно заданном формате. Эти операции обычно оформлены в виде стандартных программ и составляют основу ядра программно-математического обеспечения микро-ЭВМ. Запрограммировав самостоятельно ряд вычислительных задач большей или меньшей сложности, читатель вскоре вынужден будет обратиться к уже имеющимся библиотекам стандартных программ и пакетам прикладных программ, поскольку он убедится, какой колоссальный объем интеллектуального коллективного труда уже вложен в них и что никто в одиночку не в состоянии пройти заново весь этот путь и разработать полностью математическое обеспечение ЭВМ.
Для начала введем в память ПМ-ЭВМ программу:
014000076 MVIA, 002Q
014001 002
014 002 306 ADI, 003Q
014003 003
014 004 323 OUT, OOOQ
014005 000
014 006 166 HLT
Программа выполняет сложение двоичного числа (в данном случае 002Q), помещенного в ячейку ОЗУ по адресу 014Qt)01Q, с числом (в данном случае 003Q), помещенным в ячейку ОЗУ по адресу 014Q 003Q, и выводит результат (в данном случае 005Q) в порт 000.
Для того чтобы эти действия были исполнены, достаточно после ввода программы нажать кнопку СБРОС, а затем кнопку П — на индикаторах порта 000 высветится двоичное число 00000101, эквивалентом которого является восьмеричное число 005 Q. Чтобы сложить другие числа в диапазоне от OOOQ до 377Q, их надо поместить по указанным выше адресам, не меняя остальной части программы, и снова нажать кнопки СБРОС и П. Для вычитания числа, помещенного по адресу 014Q 003Q, из числа, помещенного по адресу 014Q 001Q, достаточно поменять команду ADI (код операции 306Q) на команду SUI (код операции 326Q). Чтобы производить операции над десятичными числами, их надо представить в двоично-кодированном виде, так чтобы каждый байт изображал двухразрядное десятичное число от 0 до 99:
десятичное двоично-кодированное восьмеричное десятичное
00 0000 0000 000
01 0000 0001 001
02 0000 0010 002
97 10010111 227
98 1001 1000 230
99 1001 1001 231
В приведенной выше программе для сложения, например, чисел 25 и 47 после команды сложения необходимо поставить команду десятичной коррекции результата сложения DAA:
014000076 MVIA.25D
014001 045
014002306 ADI.47D
014 003 107
014 004 047 DAA
014005323 OUT, OOOQ
014 006 OOU
014 007 166 HLT
В результате порт 000 после исполнения программы индицирует число 0111 0010В = 162Q=72D.
Для того чтобы проследить исполнение операции десятичной коррекции, введем в ПМ-ЭВМ следующую программу:
014000257 XRA, A
014001 306 Ml: ADI,001Q
014 002 001
014 003 047 DAA
014 004 006 MVI B, 040Q
014005 040
014006315 M2: CALL DL
014007 277
014 010 000
014011005 OCR В
014012302 JNZ, M2
014013 006
014 014 014
014015323 OUT, 002Q
014016 002
014017303 JMP, Ml
014020 001
014021 014
Программа производит примерно каждые 0,5 с суммирование содержимого аккумулятора с единицей (инкремент), выполняет операцию десятичной коррекции и выводит результат в порт 002. Операция десятичной коррекции дает правильный результат только после операции сложения. Поэтому для выполнения вычитания одного двоично-кодированного десятичного числа из другого необходимо либо заменить вьиитание прибавлением к уменьшаемому вычитаемого, представленного в дополнительном коде, а затем уже производить десятичную коррекцию результата, либо применить эквивалентные этому искусственные приемы. Для примера введем в ПМ-ЭВМ программу вычитания содержимого ячейки 014Q 005Q (здесь 28) из содержимого ячейки 014Q 007Q (здесь 75) :
014000076 MVIA, 99D
014001 231
014002306 ADI, 01D
014 003 001
014004336 SBI, 28D
014005 050
014 006 306 ADI, 75D
014 007 165
014 010 047 DAA
014011323 OUT, OOOQ 014 012000
014013166 HLT
В данной программе вычитание числа 28D из числа 99D + ID эквивалентно формированию в аккумуляторе вычитаемого в дополнительном коде. Поэтому прибавление уменьшаемого (здесь 75 D) с последующей десятичной коррекцией дает правильный результат (47 D), индицируемый портом 000.
Использование команд сложения и вычитания с переносом (заемом) позволяет организовать сложение и вычитание целых чисел неограниченной разрядности. Введем, например, в ПМ-ЭВМ программу
014 000 021 LXID, ALPHA
014 001 000
014002015
014003041 LXIH, BETA
014 004 000
014 005 016
014 006 016 MVI С, 8Н
014007 010
014010257 XRAA
014011032 Ml: LDAX D
014012216 ADCM
014 013 000 NOP
014014022 STAXD
014015043 INXH
014016023 INXD
014017015 OCR С
014020302 JNZ, Ml
014021 Oil
014 022014
014 023 166 HLT
С помощью этой программы двоичное 64-разрядное число, содержащееся в последовательных ячейках ЗУ, начиная (младшие разряды) с ячейки с символическим адресом ALPHA (здесь 015Q OOOQ), складывается с 64-разрядным числом, содержащимся в последовательных ячейках ЗУ, начиная с ячейки с символическим адресом BETA (здесь 016Q OOOQ), и результат помещается в ячейки ЗУ, начиная с ячейки с адресом ALPHA. Заменив команду NOP по адресу 014Q 013Q командой десятичной коррекции, получим программу сложения двух 16-разрядных десятичных чисел, находящихся в ячейках памяти, начиная с ячеек соответственно ALPHA и BETA.
Для вычитания десятичных 16-разрядных чисел, когда уменьшаемое располагается в ЗУ, начиная с ячейки ALPHA, а вычитаемое - начиная с ячейки BETA, получим такую программу:
014 000 021 LXI D, ALPHA
010 001 000
000 102 015
000 003 041 LXIH, BETA
000 004 000
014005 016
014 006 016 MVIC, 8H
014 007 010
014 010 067 STC
014011076 Ml: MVI A, 99D
014 012231
014013316 АС1,0
014014 000
014015226 SUBM
014 016 353 XCHG
014017206 ADDM
014 020 047 DAA
014021167 MOVM,A
014 022 353 XCHG
014 023 023 INX D
014024043 INXH
014025015 DCRC
014026302 JNZ, Ml
014027011
014030014
014031166 HLT
Результат вычитания помещается в ячейки ЗУ, начиная с ALPHA. В процессе работы с помещенными выше программами мы смогли убедиться в больших неудобствах ввода десятичной информации с помощью восьмеричной клавиатуры, поскольку каждую пару десятичных цифр нужно предварительно перевести в восьмеричный код. Можно написать специальную программу ввода десятичных цифр, использовав тот факт, что при нажатии определенных клавиш вырабатываются не только коды чисел от 0 до 7, но и коды чисел от 8 до 15. Действительно, введя в ПМ-ЭВМ следующую программу:
014 000 315 Ml: CALL, SKL
014001 177
014 002 000
014 003 323 OUT, OOOQ
014 004 000
014005303 JMP, Ml
014 006 000
014007 014
нажимая разные кнопки и наблюдая индикацию порта 000, убедимся, что при обращении к клавиатуре с помощью команды CALL SKL в аккумулятор помещаются коды в соответствии с табл. 7.7. В частности, кнопке С Б соответствует код 0000 1000, т. е. код числа 08 D, а кнопке МБ — код 0000 1001, т. е. код числа 09D. Следовательно, незначительно изменив текст программы-монитора в части анализа введенного числа, можно вводить и размещать в памяти ПМ-ЭВМ информацию непосредственно в десятичном виде. Предоставим читателю возможность самому составить такую программу и разместить ее в ОЗУ или в дополнительных микросхемах ПЗУ.
Знакомясь с литературой и технической документацией, читатель вскоре обнаружит, что большая часть стандартных программ оперирует не с десятичными числами, а с двоичными. Переход от десятичной системы к двоичной и обратно осуществляется с помощью специальных программ при вводе и соответственно при выводе информации из ЭВМ.
Рассмотрим следующую программу, переводящую пятиразрядное целое десятичное число в диапазоне от 00000 до 65535, вводимое с клавиатуры ПМ-ЭВМ (для цифры 8 используется кнопка СБ, а для цифры 9 — кнопка МБ), в 16-разрядное двоичное число, содержащееся в регистровой паре Н:
014000041 LXI H, OOOQ OOOQ
014001 000
014 002 000
014003016 MVIC, 0050
014 004 005
014005315 Ml: CALL SKL
014006 177
014 007 000
014010376 CPI, 012Q
014 Oil 012
014012322 JNC, Ml
014013 005
014014 014
014015345 PUSHH
014016321 POPD
014 017051 DADH
014 020051 DADH
014 021031 DADD
014 022051 DADH
014 023 137 MOVE, A
014 024 026 MVI D, OOOQ
014 025 000
014 026031 DADD
014 027015 OCR С
014 030302 JNZ,M1
014 031 005
014 032014
014 033 174 MOV A, H
014 034323 OUT, 001Q
014 035 001
014036175 MOV A, L
014037323 OUT, OOOQ
014 040000
014041 166 HLT
Программа обращается к ПП опроса клавиатуры SKL и при нажатии любой кнопки анализирует введенный код. Если код соответствует цифрам от 0 до 9, содержащееся в регистровой паре Н число (команды с адреса 014Q 017Q по 014Q 022Q) умножается на 10 и к нему прибавляется вновь введенное число. Программа с помощью счетчика, организованного на регистре С, отсчитывает пять таких циклов, поэтому вводимое число обязательно должно быть пятиразрядным (например, 00512). Команды с адреса 014Q 033Q используются в демонстрационных целях для вывода преобразованного в двоичный код числа в порты 001 и 000. Если программа должна использоваться в качестве ПП, то по адресу 014Q 033Q должна быть записана команда RET.
Введите программу в ПМ-ЭВМ, нажмите кнопки СБРОС и П, затем введите десятичное число 10 000, последовательно нажимая кнопки 1, О, О, О, О. В портах 001 и 000 высветится число 0010 0111 0001 0000, являющееся двоичным эквивалентом десятичного числа 10 000. Проверьте правильность работы программы, вводя другие десятичные числа, например 00512, 01024, 02048, 04096, 08192, 16384, 32768, 65535: Какие двоичные числа должны индицироваться портами 001 и 000?
Рассмотрим теперь программу преобразования целого двоичного 16-разрядного числа, содержащегося в регистровой паре D, в двоично-кодированное десятичное число, каждый разряд которого помещается, начиная с младшего, в последовательные ячейки ОЗУ, начиная с ячейки, символический адрес которой ED (машинный адрес 015Q OOOQ):
014000041 LXI H, ED
014001 000
014002 015
014003016 MVIC,005Q
014 004 005
014005066 Ml: MVI M, OOOQ
014 006 000
014007043 INXH
014010015 OCR С
014011302 JNZ,M1
014012005
014013 014
014014053 DCXH
014015001 LXI В. 33003600
014 016 360
014017 330
014020315 CALLCF
014 021 060
014022014
014023001 LXI В, 374Q030Q
014024030
014025 374
014026315 CALLCF
014027 060
014 030014
014031001 LXI В, 377Q234Q
014 032 234
014 033 377
014034315 CALLCF
014 035 060
014036 014
014037001 LXI B, 377Q366Q
014040366
014 041 377
014042315 CALLCF
014 043 060
014 044 014
014 045 163 MOVM, E
014 046 166 HLT
014 047 021 LXI D (число)
014050377
014051 377
014052166 HLT
014060345 CF: PUSH H
014 061 353 XCHG
014062011 DAD В
014063322 JNC, M2
014 064 074
014065 014
014 066 353 XCHG
014067341 POPH
014 070 064 INK M
014071303 JMP, CF
014072060
014073 014
014 074 171 M2: MOV А С
014 075 057 CMA
014 076 137 MOVE, A
014077170 MOV А, В
014100057 CMA
014 101 127 MOVD, A
014 102023 INXD
014103031 DADD
014104353 XCHG
014105341 POPH
014 106 053 OCX H
014107311 RET
Программа построена на принципе последовательного исчерпывания: каждый десятичный разряд, начиная с десятков тысяч, определяется путем подсчета количества суммирований с преобразуемым числом двоичного числа, соответствующего дополнению до 10 000, затем до 1000, затем до 100, затем до 10, каждый раз до появления переноса. Вычисленные значения засылаются в ячейки соответственно ED + 4, ED + 3, ED + 2, ED + 1. В остатке остаются единицы, засылаемые в ячейку памяти ED.
Если программа должна использоваться в качестве ПП, то по адресу 014Q 046Q должна быть записана команда RET. В данном примере для загрузки регистровой пары D использована небольшая программа, начинающаяся с адреса 014Q 047Q.
Введите программу в ПМ-ЭВМ, нажмите кнопку СБРОС, наберите число 047 и нажмите кнопки МБ и П. Регистровая пара D загружена максимальным двоичным числом (во всех разрядах единицы). Теперь нажмите кнопки СБРОС и П, затем нажмите кнопку СБРОС, наберите число 015 и нажмите кнопку СБ. Порт 002 будет индицировать число 0000 0101, т. е. двоично-десятичный код числа 05. Нажмите кнопку И - порт 002 будет индицировать 0000 ООН, т. е. 03. Последовательным нажатием кнопки И получим соответственно 05, 05, 06. Это означает, что в ячейках ОЗУ хранится число 65 535, являющееся десятичным эквивалентом максимального 16-разрядного двоичного числа. Загружайте в ячейки 014Q 050Q и 014Q 051Q различные числа. Повторяя описанную выше процедуру, можно убедиться, что преобразование осуществляется правильно.
Чтобы реализовать на ПМ-ЭВМ программируемый калькулятор, выполняющий четыре арифметические действия, приведенные выше программы необходимо дополнить программами умножения и деления (более сложные программы, в том числе программы вычисления элементарных функций, можно найти в справочной литературе, здесь они не приводятся за недостатком места).
9.2. ПРОГРАММИРУЕМОЕ УПРАВЛЯЮЩЕЕ УСТРОЙСТВО
Устройства цифровой автоматики являются областью наиболее массового применения микропроцессоров. В качестве примера конструирования управляю-
щего устройства на базе ПМ-ЭВМ рассмотрим кодовый замок, предназначенный для использования в жилом помещении или в других целях. Поставим задачу так, чтобы использовать минимум добавочного оборудования. Введем в ПМ-ЭВМ такую программу:
014 000 006 MVI В, 006Q
014 001 006
014 002 041 LXI Н, (адр. кода)
014 003 040
014 004 014
014005315 Ml: CALL SKL
014006 177
014 007 000
014010276 СМРМ
014011 302 JNZ ,M3
014012026
014013 014
014014043 INXH
014015005 DCRB
014016302 JNZ, Ml
014017005
014020014
014021076 M2: MVI A, 001Q
014 022 001
014 023 323 OUT, OOOQ
014 024 000
014025166 HLT
014026074 M3: INRA
014027323 OUT, 001Q
014 030 001
014031315 CALLDL
014 032 277
014 033 000
014 034 303 JMP, M3
014 035 026
014036014
014040001 КОД: 123481
014041 002
014 042 003
014 043 004
014 044 010
014 045 001
Здесь с помощью команды MVI В организован счетчик количества цифр в наборе кодового замка. Командой CALL SKL непрерывно опрашивается клавиатура, при нажатии одной из кнопок полученный код сравнивается с кодом, хранящимся в ячейках памяти. Если коды не совпадают, происходит переход по метке МЗ к части программы, предназначенной для подачи сигнала тревоги (в порт 001 выводится инкрементируе-мое через каждый 0,01 с содержимое аккумулятора). Если коды совпадают, программа возвращается к опросу клавиатуры (метка Ml) и ожидает нового нажатия кнопки, при котором происходит сравнение полученного кода с содержимым следующей ячейки памяти, и т. д. до тех пор, пока количество нажатий не будет равно запрограммированному командой MVI В. Тогда в порт 000 будет выведено число 001Q, т. е. загорится светодиодный индикатор, соответствующий младшему разряду. Сигнал с младшего разряда порта 000 может быть использован для управления электромагнитом, отпирающим замок.
Введем программу в ПМ-ЭВМ, нажмем кнопки СБРОС и П, а затем поочередно кнопки 1, 2, 3, 4, СБ, 1, соответствующие кодовой комбинации замка (кнопка СБ соответствует цифре 8, а кнопка МБ - цифре 9).
При нажатии последней кнопки на индикаторах порта 000 появится число 001Q. Для возврата к исходному состоянию необходимо снова нажать кнопки СБРОС и П. Теперь при наборе кода сделайте ошибку - тотчас в порте 001 начинают мигать светодиодные индикаторы, а если между выходом порта 001 (вывод 16 микросхемы D18) и источником + 5 В через резистор 200 Ом подключить наушник или репродуктор, послышится тревожное гудение, прекратить которое можно, только нажав кнопку СБРОС.
Вводя разные числа в ячейку ОЗУ по адресу 014Q 001Q, можно изменять количество цифр в кодовой комбинации, а вводя различные числа в ячейки ОЗУ, начиная с 014Q 040Q -задавать различные кодовые комбинации. Таким образом, не используя никакого добавочного оборудования, мы промоделировали работу кодового замка. Для реализации кодового замка, как говорят, "в железе" необходимо вынести в наборное поле замка кнопки, параллельные кнопкам клавиатуры 0-7, СБ, МБ, СБРОС, П. Последние две кнопки необходимы, чтобы при неправильном наборе вернуться к исходному состоянию. Кроме того, нужно организовать управление механизмом замка, а для того чтобы после случайного прекращения питания замок правильно функционировал, программу вместе с кодовой комбинацией необходимо хранить в ПЗУ.
Мы видим, что при всей простоте реализации кодовый замок на базе ПМ-ЭВМ представляет законченную систему цифрового управления: он хранит программу и исходные данные (уставки), принимает входные управляющие воздействия (нажатия кнопок), вырабатывает выходные управляющие сигналы (сигнал тревоги или сигнал разрешения для механизма замка). Читатель может по своему усмотрению усложнить алгоритм работы замка с целью повышения безопасности или с целью упрощения коммуникаций.