· на очередном шаге произошло переполнение интегральной суммы;
· переполнение после сложения
и интегральной суммы;· переполнение при выполнении операции (1).
Результатом переполнения является следующая последовательность действий:
· на выходе сигнал FFFFH;
· обнуляется интегральная сумма.
При этом сам пользователь должен контролировать: чтобы разность двух соседних сигналов
и не превышала 216.Метка | Мнемокод | Тактов | Байт | Примечания |
Задание констант | ||||
PRT_IN_LO = 00H | ||||
PRT_IN_HI = 01H | Старший байт входного сигнала | |||
KP_LO = 02H | ||||
KP_HI = 03H | ||||
KI_LO = 04H | ||||
KI_HI = 05H | ||||
KD_LO = 06H | ||||
KD_HI = 07H | ||||
PRT_OUT_HI = 08H | ||||
PRT_OUT_LO= 09H | ||||
ST_PT = 9FFFH | Указатель стека | |||
В соотвествии с табл. 4 также указываются значения:Int_sum, Sign, Number, PE, CE, KP, KI, KD, WC – WC +13, WC + 17 | ||||
Основная программа | ||||
ORG 0000H | Программа начинается по адресу 0000H | |||
JMP START | 10 | 3 | ||
NOP | 4 | 1 | ||
NOP | 4 | 1 | ||
NOP | 4 | 1 | ||
NOP | 4 | 1 | ||
JMP INT | 10 | 3 | ||
START: | DI | 4 | 1 | Запрет прерываний |
Запись значений коэффициентов (со знаками) в память | ||||
MVI A, 0 | 7 | 2 | Обнуление ячейки SIGN | |
STA SIGN | 13 | 3 | ||
IN KP_LO | 10 | 2 | Запись в ячейку с адресом KP значения младшего байта KP | |
LXI H, KP | 10 | 3 | ||
STAX H | 7 | 1 | ||
IN KP_HI | 10 | 2 | Запись в ячейку с адресом INT_SUM+9 значения старшего байта KP | |
INX H | 5 | 1 | ||
STAX H | 7 | 1 | ||
IN KI_LO | 10 | 2 | Занесение остальных значений коэффициентов в соответсвующие ячейки памяти, коэффициент KD располагается также в регистрах А: В | |
INX H | 5 | 1 | ||
STAX H | 7 | 1 | ||
IN KI_HI | 10 | 2 | ||
INX H | 5 | 1 | ||
STAX H | 7 | 1 | ||
IN KD_LO | 10 | 2 | ||
INX H | 5 | 1 | ||
STAX H | 7 | 1 | ||
IN KD_HI | 10 | 2 | ||
INX H | 5 | 1 | ||
STAX H | 7 | 1 | ||
Определение знаков коэффициентов, выделения модулей и записи знаков в соответствующий бит знаковой ячейки | ||||
MVI D, 3 | 7 | 2 | Загрузить в регистр D количество циклов | |
@@1: | LDAX H | 7 | 1 | Запись текущего коэффициента в B: C, старший байт также остаётся в аккумуляторе. |
MOV C, A | 5 | 1 | ||
DCX H | 5 | 1 | ||
LDAX H | 7 | 1 | ||
MOV B, A | 5 | 1 | ||
RAL | 4 | 1 | Занесение в признак переноса старшего бита | |
JNC POSNUM | 17 | 3 | Если старший бит = 0, то перейти к POSNUM (positive number) – не требуется уточнение знака и изменения знаковой ячейки | |
MOV A, B | 5 | 1 | Загрузка в аккумулятор младшего байта | |
XRI FFH | 7 | 2 | Дополнение до двух и прибавление единицы – выделение модуля. | |
ADI 1 | 7 | 2 | ||
MOV B, A | 5 | 1 | Сохранение младшего байта модуля в регистре В | |
MOV A, C | 5 | 1 | Помещение в аккумулятор старшего байта | |
XRI FFH | 7 | 2 | Дополнение до двух и учёт переноса. | |
ACI 0 | 7 | 2 | ||
MOV C, A | 5 | 1 | Поместить в регистр С старший байт модуля | |
XRA A | 7 | 1 | Сброс признака переноса | |
MOV E, D | 5 | 1 | ||
MVI A, 1 | 7 | 2 | ||
@@2: | RAL | 4 | 1 | Смещение единицы в соответствующий разряд и сохранение в регистре Е |
DCX E | 5 | 1 | ||
JNZ @@2 | 17 | 3 | ||
Итого @@2 | 156 | |||
MOV E, A | 5 | 1 | ||
LDA SIGN | 13 | 3 | Загрузить в соответствующий бит ячейки SIGN – 1 (прямая адресация) | |
ADD E | 4 | 1 | ||
STA SIGN | 13 | 3 | ||
POSNUM: | MOV M, C | 7 | 1 | Сохранить модуль коэффициента в соответсвующих ячейках. |
DCX H | 5 | 1 | ||
MOV M, B | 7 | 1 | ||
DCX H | 5 | 1 | Уменьшить адрес на единицу – указатель на старший байт следующего коэффициента | |
DCX D | 5 | 1 | Уменьшить счётчик цикла | |
JNZ @@1 | 17 | 3 | Если не обработаны все коэффициенты то перейти к @@1. По окончании в регистрах B: С содержится значение коэффициента KP. | |
Итого@@1 | 750 | |||
LXI SP, ST_PT | 10 | 3 | Установка вершины стека | |
EI | 4 | 1 | Разрешение прерываний | |
HLT | 7 | 1 | Ожидание прерывания | |
Итого(START) | 939 | 129 | ||
Программа обработки прерывания | ||||
Выявление модуля и знака | ||||
INT: | IN PRT_IN_LO | 10 | 2 | Загрузить значение в регистры В: С и в память |
STA СE | 13 | 3 | СE+1: СE (число со знаком) | |
MOV C, A | 5 | 1 | ||
IN PRT_IN_HI | 10 | 2 | ||
STA СE+1 | 13 | 3 | ||
MOV B, A | 5 | 1 | ||
LXI H, SIGN | 10 | 3 | Обнуление младшего бита SIGN | |
LDAX H | 7 | 1 | ||
ANI 00001110B | 7 | 2 | ||
STAX H | 7 | 1 | ||
RAL | 4 | 1 | Проверка знака , операции аналогичны приведённым выше | |
JNC POSNUM2 | 17 | 3 | ||
MOV A, C | 5 | 1 | ||
XRI FFH | 7 | 2 | ||
ADI 0 | 7 | 2 | ||
MOV C, A | 5 | 1 | ||
MOV A, B | 5 | 1 | ||
XRI FFH | 7 | 2 | ||
ACI 0 | 7 | 2 | ||
MOV B, A | 5 | 1 | ||
LDAX H | 7 | 1 | Помещение в младший бит SIGN единицы | |
ADI 1 | 7 | 2 | ||
STAX H | 7 | 1 | ||
LXI H, WC | 10 | 3 | Помещение значения в память WC+1: WC (модуль) | |
POSNUM2: | MOV A, C | 5 | 1 | |
STAX H | 7 | 1 | ||
INX H | 5 | 1 | ||
MOV A, B | 5 | 1 | ||
STAX H | 7 | 1 | ||
Умножение | ||||
Запись коэффициента KP в ячейки памяти WC+3: WC +2 | ||||
LDA KP | 13 | 3 | ||
STA WC+2 | 13 | 3 | ||
LDA KP+1 | 13 | 3 | ||
STA WC+3 | 13 | 3 | ||
MVI A, 1 | 7 | 2 | Запись в NUMBER значение 1 – идентификатор коэффициента KP | |
STA NUMBER | 13 | 3 | ||
LXI H, WC + 13 | 10 | 3 | Необходимый параметр процедуры – адрес младшего байта результата | |
CALL MUL16_16 | 4146 | NONE | ||
Умножение | ||||
MVI A, 2 | 7 | 2 | Запись в NUMBER значение 2 – идентификатор коэффициента KI | |
LDA KI | 13 | 3 | (58 тактов, 12 байт) – (42 такта – 12 байт) | |
STA WC+2 | 13 | 3 | Запись KI в ячейки множителя | |
LDA KI | 13 | 3 | ||
STA WC+3 | 13 | 3 | ||
LXI H, WC + 17 | 10 | 3 | ||
CALL MUL16_16 | 4146 | NONE | ||
Увеличение интегральной суммы | ||||
LXI H, WC + 17 | 10 | 3 | Инициализация указателей | |
LXI D, INT_SUM | 10 | 3 | ||
MVI B, 4 | 7 | 2 | Инициализация счётчика | |
XRA A | 7 | 1 | Сброс признака переноса | |
LOOP1: | LDAX D | 7 | 1 | Загрузка первого операнда |
ADC M | 7 | 1 | Сложение | |
STAX D | 7 | 1 | Запоминание операнда | |
DCR B | 5 | 1 | Декремент счётчика | |
JZ DONE1 | 17 | 3 | Сложение закончено? | |
INX H | 5 | 1 | Переход к следующему байту | |
INX D | 5 | 1 | ||
JMP LOOP1 | 10 | 3 | Организация цикла | |
Итого LOOP1 | 252 | |||
DONE1: | JC GLUCK | 17 | 3 | При переносе перейти к обработке переполнения |
Умножение | ||||
LDA WC | 13 | 3 | Загрузка в регистры B: C | |
MOV C, A | 5 | 1 | ||
LDA WC+1 | 13 | 3 | ||
MOV B, A | 5 | 1 | ||
LDA SIGN | 13 | 3 | Проверить знак | |
RAR | 4 | 1 | ||
JNC POSNUM3 | 17 | 3 | ||
MOV A, C | 5 | 1 | Если знак отрицательный, то перевести в дополнительный код. | |
XRI FFH | 7 | 2 | ||
ADI 0 | 7 | 2 | ||
MOV C, A | 5 | 1 | ||
MOV A, B | 5 | 1 | ||
XRI FFH | 7 | 2 | ||
ACI 0 | 7 | 2 | ||
MOV B, A | 5 | 1 | ||
POSNUM3: | LXI H, PE | 10 | 3 | Загрузить предыдущее значение в регистры В: С |
MOV A, C | 5 | 1 | ||
ADD M | 7 | 1 | ||
MOV C, A | 5 | 1 | ||
INX H | 5 | 1 | ||
MOV A, B | 5 | 1 | ||
ADC M | 7 | 1 | ||
MOV B, A | 5 | 1 | ||
RAL | 4 | 1 | Запись в младший бит SIGN знака разности | |
MVI E, 11111110B | 7 | 2 | ||
MOV A, E | 5 | 1 | ||
ACI 0 | 7 | 2 | ||
MOV E, A | 5 | 1 | ||
LDA SIGN | 13 | 3 | ||
ANA E | 4 | 1 | ||
STA SIGN | 13 | 3 | ||
MOV A, B | 5 | 1 | Проверить ещё раз разность на перенос | |
RAL | 4 | 1 | ||
JNC POSNUM4 | 17 | 3 | ||
MOV A, C | 5 | 1 | Далее процедура инвертирования знака | |
XRI FFH | 7 | 2 | ||
ADI 0 | 7 | 2 | ||
MOV C, A | 5 | 1 | ||
MOV A, B | 5 | 1 | ||
XRI FFH | 7 | 2 | ||
ACI 0 | 7 | 2 | ||
MOV B, A | 5 | 1 | ||
POSNUM4: | STA WC | 13 | 3 | Помещение разности в ячейку множимого |
MOV C, A | 5 | 1 | ||
STA WC+1 | 13 | 3 | ||
LDA KD | 13 | 3 | Помещение КD в ячейку множителя | |
STA WC+2 | 13 | 3 | ||
LDA KD+1 | 13 | 3 | ||
STA WC+3 | 13 | 3 | ||
LXI H, WC+17 | 10 | 3 | ||
CALL MUL16_16 | 4146 | NONE | ||
Сложение | ||||
LXI H, INT_SUM | 10 | 3 | Операция аналогичная увеличению интегральной суммы. Результат сложения в WC+16 – WC+13 | |
LXID, WC + 13 | 10 | 3 | ||
MVIB, 4 | 7 | 2 | ||
XRAA | 4 | 1 | ||
LOOP2: | LDAXD | 7 | 1 | |
ADCM | 7 | 1 | ||
STAXD | 7 | 1 | ||
DCRB | 5 | 1 | ||
JZ DONE2 | 17 | 3 | ||
INX H | 5 | 1 | ||
INX D | 5 | 1 | ||
JMP LOOP2 | 10 | 3 | ||
Итого LOOP2 | 252 | |||
DONE2: | JC GLUCK | 17 | 3 | |
Вычисление (1) | ||||
LXI H, WC + 17 | 10 | 3 | Операция аналогичная увеличению интегральной суммы | |
LXI D, WC + 13 | 10 | 3 | ||
MVI B, 4 | 7 | 2 | ||
XRA A | 4 | 1 | ||
LOOP3: | LDAX D | 7 | 1 | |
ADC M | 7 | 1 | ||
STAX D | 7 | 1 | ||
DCR B | 5 | 1 | ||
JZ DONE3 | 17 | 3 | ||
INX H | 5 | 1 | ||
INX D | 5 | 1 | ||
JMP LOOP3 | 10 | 3 | ||
Итого LOOP3 | 252 | |||
DONE3: | JNC GOOD | 17 | 3 | Если нет переноса, то пропустить обработку переполнения |
Обработка переполнений | ||||
GLUCK: | MVI A, FFH | 7 | 2 | Запись в выдаваемые старшие два байта значения FFFFH |
LXI H, WC + 15 | 10 | 3 | ||
MOV M, A | 7 | 1 | ||
INX H | 5 | 1 | ||
MOV M, A | 7 | 1 | ||
LXI H, INT_SUM | 10 | 3 | Обнуление интегральной суммы | |
MVI B, 4 | 7 | 2 | ||
MVI A, 00H | 7 | 2 | ||
LOOP4: | STAX D | 7 | 1 | |
DCR B | 5 | 1 | ||
JZ GOOD | 17 | 3 | ||
INX D | 5 | 1 | ||
JMP LOOP4 | 10 | 3 | ||
Итого LOOP4 | 176 | |||
Выдача результата | ||||
GOOD: | LDA WC + 15 | 13 | 3 | Выдача старших шестнадцати бит суммы |
OUT PRT_OUT_LO | 10 | 2 | ||
LDA WC + 16 | 13 | 3 | ||
OUT PRT_OUT_HI | 10 | 2 | ||
LDA CE | 13 | 3 | Текущее значение становится предыдущим. | |
STA PE | 13 | 3 | ||
LDA CE+1 | 13 | 3 | ||
STA PE+1 | 13 | 3 | ||
RET | 10 | 1 | ||
Итого RET | 14444 | 293 | ||
Процедура умножения шестнадцатибитных чисел | ||||
MUL16_16: | Расположение в памяти исходных данных (4 байта):Множимое – WC+1: WCМножитель – WC+3: WC+2Расположение результата (4 байта):H-L – адрес младшего байта результатаЗадействуются все регистры | |||
PUSH H | 11 | 3 | Запомнить адрес младшего байта результата | |
LXI H, WC | 10 | 3 | ||
LDAX H | 7 | 1 | Вычисление и помещение в память блока 1×3 (см. рис. 4 и табл. 4) | |
MOV E, A | 5 | 1 | ||
INX H | 5 | 1 | ||
INX H | 5 | 1 | ||
LDAX H | 7 | 1 | ||
MOV D, A | 5 | 1 | ||
CALL MUL8_8 | 820 | NONE | ||
MOV A, С | 5 | 1 | ||
STA WC + 5 | 13 | 3 | ||
MOV A, B | 5 | 1 | ||
STA WC + 6 | 13 | 3 | ||
LDAX H | 7 | 1 | Вычисление и помещение в память блока 2×3 (см. рис. 4 и табл. 4) | |
MOV E, A | 5 | 1 | ||
DCX H | 5 | 1 | ||
LDAX H | 7 | 1 | ||
MOV D, A | 5 | 1 | ||
CALL MUL8_8 | 820 | NONE | ||
MOV A, С | 5 | 1 | ||
STA WC + 7 | 13 | 3 | ||
MOV A, B | 5 | 1 | ||
STA WC + 8 | 13 | 3 | ||
DCX H | 5 | 1 | Вычисление и помещение в память блока 1×4 (см. рис. 4 и табл. 4) | |
LDAX H | 7 | 1 | ||
MOV E, A | 5 | 1 | ||
INX H | 5 | 1 | ||
INX H | 5 | 1 | ||
INX H | 5 | 1 | ||
LDAX H | 7 | 1 | ||
MOV D, A | 5 | 1 | ||
CALL MUL8_8 | 820 | NONE | ||
MOV A, С | 5 | 1 | ||
STA WC + 9 | 13 | 3 | ||
MOV A, B | 5 | 1 | ||
STA WC + 10 | 13 | 3 | ||
LDAX H | 7 | 1 | Вычисление и помещение в память блока 2×4 (см. рис. 4 и табл. 4) | |
MOV D, A | 5 | 1 | ||
DCX H | 5 | 1 | ||
DCX H | 5 | 1 | ||
LDAX H | 7 | 1 | ||
MOV E, A | 5 | 1 | ||
CALL MUL8_8 | 820 | NONE | ||
MOV A, С | 5 | 1 | ||
STA WC + 11 | 13 | 3 | ||
MOV A, B | 5 | 1 | ||
STA WC + 12 | 13 | 3 | ||
Сложение промежуточных результатов | ||||
LXI H, WC + 6 | 10 | 3 | ||
LDAX H | 7 | 1 | Загрузить ячейку WC+6 | |
MOV D, A | 5 | 1 | ||
INX H | 5 | 1 | ||
LDAX H | 7 | 1 | Загрузить ячейку WC+7 | |
ADD D | 4 | 1 | ||
MOV D, A | 5 | 1 | ||
INX H | 5 | 1 | ||
LDAX H | 7 | 1 | Загрузить ячейку WC+8 | |
ACI 0 | 7 | 2 | Прибавить перенос к третьему байту | |
MOV C, A | 5 | 1 | ||
LDA WC+12 | 13 | 3 | ||
ACI 0 | 7 | 2 | Прибавить перенос к четвёртому байту | |
MOV B, A | 5 | 1 | ||
INX H | 5 | 1 | ||
LDAX H | 7 | 1 | Загрузить ячейку WC+9 | |
MOV E, A | 5 | 1 | ||
MOV A, D | 5 | 1 | ||
ADD E | 4 | 1 | ||
MOV D, A | 5 | 1 | Регистр D содержит второй байт | |
MOV A, C | 5 | 1 | ||
ACI 0 | 7 | 2 | Прибавить перенос к третьему байту | |
MOV C, A | 5 | 1 | ||
MOV A, B | 5 | 1 | ||
ACI 0 | 7 | 2 | Прибавить перенос к четвёртому байту | |
MOV B, A | 5 | 1 | ||
INX H | 5 | 1 | ||
LDAX H | 7 | 1 | Загрузить ячейку WC+10 | |
ADD C | 4 | 1 | ||
MOV C, A | 5 | 1 | ||
MOV A, B | 5 | 1 | ||
ACI 0 | 7 | 2 | Прибавить перенос к четвёртому байту | |
MOV B, A | 5 | 1 | ||
INX H | 5 | 1 | ||
LDAX H | 7 | 1 | Загрузить ячейку WC+11 | |
ADD C | 4 | 1 | ||
MOV C, A | 5 | 1 | Регистр С содержит третий байт | |
MOV A, B | 5 | 1 | ||
ACI 0 | 7 | 2 | Прибавить перенос к четвёртому байту | |
MOV B, A | 5 | 1 | Регистр В содержит четвёртый байт | |
STA NUMBER | 13 | 3 | Загрузка в регистр Е содержимого ячейки памяти NUMBER, числа, которое определеняет, какой из коэффициентов является множителем | |
MOV E, A | 5 | 1 | ||
STA SIGN | 13 | 3 | Загрузить ячейку знаков | |
RAR | 4 | 1 | Если знак первого сомножителябыл отрицательный, то регистр H содержит 1, если положительный – 0. | |
MVI A, 0 | 10 | 2 | ||
ACI 0 | 7 | 2 | ||
MOV H, A | 5 | 1 | ||
@@3: | RAR | 4 | 1 | Помещение значащего для этого коэффициента бита в признак переноса и последующее сложение с содержимым регистра H |
DCR E | 5 | 1 | ||
JNZ @@3 | 17 | 3 | ||
Итого @@3 | 78 | |||
MOV A, H | 5 | 1 | ||
ACI 0 | 7 | 1 | ||
RAR | 4 | 1 | Сумма минусов чётная? Если нет, то необходимо инвертировать результат | |
JNC NO_INVER | 17 | 3 | ||
STA WC + 5 | 13 | 3 | Загрузить в аккумулятор первый байт произведения | |
XRI FFH | 7 | 2 | ||
ADI 1 | 7 | 2 | ||
POP H | 11 | 1 | Вернуть значение H-L из стека | |
STAX H | 7 | 1 | Сохранить значение первого байта по указанному адресу | |
INX H | 5 | 1 | ||
MOV A, D | 5 | 1 | ||
XRI FFH | 7 | 2 | ||
ACI 0 | 7 | 2 | ||
STAX H | 7 | 1 | Сохранить значение второго байта | |
INX H | 5 | 1 | ||
MOV A, C | 5 | 1 | ||
XRI FFH | 7 | 2 | ||
ACI 0 | 7 | 2 | ||
STAX H | 7 | 1 | Сохранить значение третьего байта | |
INX H | 5 | 1 | ||
MOV A, В | 5 | 1 | ||
XRI FFH | 7 | 2 | ||
ACI 0 | 7 | 2 | ||
STAX H | 7 | 1 | Сохранить значение четвёртого байта | |
NO_INVER: | RET | 10 | 1 | Конец процедуры |
Итого MUL16_16 | 4135 | 168 | ||
MUL8_8: | Осуществляет умножение восьмибитных чиселМножитель – ЕМножимое – DДвухбайтный результат – BC Задействуется регистр: L | |||
PUSH H | 11 | 1 | Сохранение значение регистровой пары H-L | |
LXI B, 0 | 10 | 3 | Сброс частичной суммы | |
MVI L, 8 | 7 | 2 | Загрузка счётчика | |
NEXT_BIT: | MOV A, E | 5 | 1 | Множитель в аккумулятор |
RAR | 4 | 1 | Поместить анализируемый бит в признак переноса | |
MOV E, A | 5 | 1 | Возврат сдвинутого множителя | |
JNC NO_ADD | 17 | 3 | Бит множителя равен нулю? | |
MOV A, B | 5 | 1 | Нет | |
ADD D | 4 | 1 | Прибавление множимого | |
MOV B, A | 5 | 1 | Возврат старшей частичной суммы | |
NO_ADD: | MOV A, B | 5 | 1 | |
RAR | 4 | 1 | Сдвиг частичной суммы | |
MOV B, A | 5 | 1 | ||
MOV A, C | 5 | 1 | ||
RAR | 4 | 1 | ||
MOV C, A | 5 | 1 | Возврат младшей частичной суммы | |
DCR L | 5 | 1 | ||
JNZ NEXT_BIT | 17 | 3 | Организация цикла | |
Итого NEXT_BIT | 760 | |||
POP H | 11 | 1 | Возвращение сохранённой регистровой пары H-L | |
RET | 10 | 1 | Конец процедуры умножения | |
Итого MUL8_8 | 809 | 27 | ||
Итого вся программа | 15419 | 627 |
В данной работе была разработана МПС на базе восьмиразрядного МП Z80. Довольно простое аппаратное решение дополняется весьма длинной программой на языке Ассемблер, которая занимает в памяти ПЗУ 627 байт. Программа выполняется примерно за 16000 (в самом худшем случае) тактов МП. Это накладывает определённые ограничения на частоту входного синхросигнала. Т.к. входной код синхронизирован по срезу, а выходной должен быть синхронизирован по фронту, то в простейшем случае (реализованный вариант) работа программы должна укладываться в половину периода синхросигнала.