· на очередном шаге произошло переполнение интегральной суммы;
· переполнение после сложения
· переполнение при выполнении операции (1).
Результатом переполнения является следующая последовательность действий:
· на выходе сигнал FFFFH;
· обнуляется интегральная сумма.
При этом сам пользователь должен контролировать: чтобы разность двух соседних сигналов
| Метка | Мнемокод | Тактов | Байт | Примечания |
| Задание констант | ||||
| 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 | Помещение значения | |
| 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 | Загрузка | |
| 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 (в самом худшем случае) тактов МП. Это накладывает определённые ограничения на частоту входного синхросигнала. Т.к. входной код синхронизирован по срезу, а выходной должен быть синхронизирован по фронту, то в простейшем случае (реализованный вариант) работа программы должна укладываться в половину периода синхросигнала.