Zilog Z80/Система команд/INI
Материал из Emuverse.
| Этот документ создан для Emuverse и распространяется на условиях мультилицензии GNU FDL + CC-BY-SA-3.0. |
Найденная в Интернете информация сильно отличается от официальных данных (особенно, в отношении флагов N и CY). Все сказанное ниже относится к блочным командам ввода-вывода INI/INIR/OUTI/OTIR и IND/INDR/OUTD/OTDR.
Флаги устанавливаются следующим образом:
- S, Z, F5, F3 из декремента B (официально — S неизвестен; информация по Z совпадает);
- N — копия 7-го бита значения, полученного/переданного в порт (по официальным данным равен 1);
Далее для получения CY (официально — не меняется) и HC (официально — неизвестен):
- Прибавить к значению регистра C единицу, если инструкция увеличивала HL, иначе отнять единицу;
- Добавить к этому значению байт, полученный или переданный в порт;
- Скопировать признак переноса этой операции во флаги CY и HY (то есть они будут одинаковые).
PV (официально — неизвестен) зависит от значения регистров B, C и переданного байта (по информации Pedro Gimeno (pgimeno@geocities.com)):
- Для INI/INIR/OUTI/OTIR
1. Вычисление первой промежуточной переменной Temp1(С.1 обозначает 1-й бит регистра и т. д., inp — переданный байт):
| C.1 | C.0 | inp.1 | inp.0 | Temp1 |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 1 | 0 |
| 0 | 0 | 1 | 0 | 1 |
| 0 | 0 | 1 | 1 | 0 |
| 0 | 1 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 1 |
| 0 | 1 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 | 1 |
| 1 | 0 | 0 | 0 | 1 |
| 1 | 0 | 0 | 1 | 0 |
| 1 | 0 | 1 | 0 | 1 |
| 1 | 0 | 1 | 1 | 1 |
| 1 | 1 | 0 | 0 | 0 |
| 1 | 1 | 0 | 1 | 1 |
| 1 | 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 1 | 0 |
2. Вычисление второй промежуточной переменной:
Если (B AND 0xF = 0) то
Temp2 = Parity(B) XOR (B.4 OR (B.6 AND NOT B.5))
иначе
Temp2 = Parity(B) XOR (B.0 OR (B.2 AND NOT B.1))
где Parity - обычная операция вычисления четности
Реально данную операцию проще выполнять по таблице:
0123456789ABCDEF <- (нижний полубайт B)
00 0011010011001011
10 0100101100110100
20 1100101100110100
30 1011010011001011
40 0100101100110100
50 1011010011001011
60 0011010011001011
70 0100101100110100
80 1100101100110100
90 1011010011001011
A0 0011010011001011
B0 0100101100110100
C0 1011010011001011
D0 0100101100110100
E0 1100101100110100
F0 1011010011001011
^
(Верхний полубайт B)
Тогда PV = Temp1 XOR Temp2 XOR C.2 XOR inp.2
- IND/INDR/OUTD/OTDR
Аналогично INI, только отличается первая таблица:
| C.1 | C.0 | inp.1 | inp.0 | Temp1 |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 1 | 1 |
| 0 | 0 | 1 | 0 | 0 |
| 0 | 0 | 1 | 1 | 0 |
| 0 | 1 | 0 | 0 | 1 |
| 0 | 1 | 0 | 1 | 0 |
| 0 | 1 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 | 1 |
| 1 | 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 1 | 0 |
| 1 | 0 | 1 | 0 | 1 |
| 1 | 0 | 1 | 1 | 0 |
| 1 | 1 | 0 | 0 | 0 |
| 1 | 1 | 0 | 1 | 1 |
| 1 | 1 | 1 | 0 | 0 |
| 1 | 1 | 1 | 1 | 1 |
