Zilog Z80/Система команд
|   | Этот документ создан для Emuverse и распространяется на условиях лицензии CC-BY-SA-3.0. | 
В этой стьтье и ее подстраницах представлены все необходимые данные для создания полноценного эмулятора процессора Z80, включая все недокументированные команды, флаги и особенности поведения в разных режимах (по крайнем мере те, что удалось найти). Статья написана на основе фирменной документации, а также большого количества материалов в Интернете, в основном, на английском языке.
Статья написана с точки зрения создателя эмулятора — максимум сведений по каждой команде приведен в общей таблице (за исключением тех случаев, когда это невозможно в силу объема), вместо словесных описаний большинства команд приводятся алгоритмы их работы. Команды перечислены в порядке, удобном для написания эффективного блока декодирования, поэтому принцип увеличения кодов сохраняется не везде.
Подразумевается, что читатель знаком с базовыми принципами и архитектурой микропроцессоров, поэтому объяснения многих понятий, без знания которых приступать к написанию эмулятора бессмысленно, опущены.
Для удобства работы с большими таблицами все условные обозначения приведены после них. Часть объемных материалов, например, по эмуляции команды DAA, вынесено на подстраницы.
Список команд
Команды без префикса
| Код | Данные | Команда | Действие | Флаги | Такты | Байты | Примечание | |
|---|---|---|---|---|---|---|---|---|
| 2 | 16 | SZ5H3VNC | ||||||
| Без префикса | ||||||||
| Группа 00 | ||||||||
| 00 000 000 | 00 | NOP | -------- | 4 | 1 | |||
| 00 001 000 | 08 | EX AF, AF' | AF <-> AF' | ******** | 4 | 1 | ||
| 00 010 000 | 10 | d | DJNZ d | B <- B-1 Если B<>0 то PC <- PC+d | -------- | 13/8 | 2 | PC равен адресу следующей за DJNZ команды | 
| 00 011 000 | 18 | d | JR d | PC <- PC+d | -------- | 12 | 2 | PC равен адресу следующей команды | 
| 00 1СС 000 | d | JR СС, d | Если СС то PC <- PC+d | -------- | 12/7 | 2 | PC равен адресу следующей команды СС включает первые 4 значения CCC | |
| 00 RP0 001 | nn | LD RP, nn | RP <- nn | -------- | 10 | 3 | ||
| 00 RP1 001 | ADD HL, RP | HL <- HL + RP | --***-0C | 11 | 1 | F5,H,F3 берутся по результатам сложения старших байтов | ||
| 00 0X0 010 | LD [X], A | [X] <- A | -------- | 7 | 1 | X=0 => BC, X=1 => DE | ||
| 00 0X1 010 | LD A, [X] | A <- [X] | -------- | 7 | 1 | X=0 => BC, X=1 => DE | ||
| 00 100 010 | 22 | nn | LD [nn], HL | [nn] <- HL | -------- | 16 | 3 | |
| 00 101 010 | 2A | nn | LD HL, [nn] | HL <- [nn] | -------- | 16 | 3 | |
| 00 110 010 | 32 | nn | LD [nn], A | [nn] <- A | -------- | 13 | 3 | |
| 00 111 010 | 3A | nn | LD A, [nn] | A <- [nn] | -------- | 13 | 3 | |
| 00 RP0 011 | INC RP | RP <- RP+1 | -------- | 6 | 1 | |||
| 00 RP1 011 | DEC RP | RP <- RP-1 | -------- | 6 | 1 | |||
| 00 SSS 100 | INC SSS | SSS <- SSS+1 | SZ5H3V0- | 4/11/19* | 1 | V=1, если SSS=7F до операции | ||
| 00 SSS 101 | DEC SSS | SSS <- SSS-1 | SZ5H3V1- | 4/11/19* | 1 | V=1, если SSS=80 до операции | ||
| 00 DDD 110 | d | LD DDD, d | DDD <- d | -------- | 7/7/15* | 2 | ||
| 00 000 111 | 07 | RLCA | Цикл. сдвиг A влево, CY<-A7 | --503-0C | 4 | 1 | См. #Команды сдвига | |
| 00 001 111 | 0F | RRCA | Цикл. сдвиг A вправо, CY<-A0 | --503-0C | 4 | 1 | См. #Команды сдвига | |
| 00 010 111 | 17 | RLA | Цикл. сдвиг A+CY влево | --503-0C | 4 | 1 | См. #Команды сдвига | |
| 00 011 111 | 1F | RRA | Цикл. сдвиг A+CY вправо | --503-0C | 4 | 1 | См. #Команды сдвига | |
| 00 100 111 | 27 | DAA | Десятичная коррекция | SZ5*3P-* | 4 | 1 | См. /DAA | |
| 00 101 111 | 2F | CPL | A <- NOT A | --*1*-1- | 4 | 1 | F3 и F5 из A | |
| 00 110 111 | 37 | SCF | CY = 1 | --*0*-01 | 4 | 1 | F3 и F5 из A | |
| 00 111 111 | 3F | CCF | CY <- NOT CY | --***-0C | 4 | 1 | H <- старый C, F3 и F5 из A | |
| Группа 01 | ||||||||
| 01 110 110 | 76 | HALT | -------- | 4 | 1 | Повторяет циклы NOP до прерывания или сброса | ||
| 01 DDD 110 | LD DDD, [HL] | DDD <- [HL] | -------- | 7/15* | 1 | |||
| 01 110 SSS | LD [HL], SSS | [HL] <- SSS | -------- | 7/15* | 1 | |||
| 01 DDD SSS | LD DDD, SSS | DDD <- SSS | -------- | 4 | 1 | DDD и SSS не равны 110 | ||
| Группа 10 | ||||||||
| 10 000 SSS | ADD A, SSS | A <- A+SSS | SZ5H3V0C | 4/7/15* | 1 | |||
| 10 001 SSS | ADC A, SSS | A <- A+SSS+CY | SZ5H3V0C | 4/7/15* | 1 | |||
| 10 010 SSS | SUB A, SSS | A <- A-SSS | SZ5H3V1C | 4/7/15* | 1 | |||
| 10 011 SSS | SBC A, SSS | A <- A-SSS-CY | SZ5H3V1C | 4/7/15* | 1 | |||
| 10 100 SSS | AND A, SSS | A <- A AND SSS | SZ513P00 | 4/7/15* | 1 | |||
| 10 101 SSS | XOR A, SSS | A <- A XOR SSS | SZ503P00 | 4/7/15* | 1 | |||
| 10 110 SSS | OR A, SSS | A <- A OR SSS | SZ503P00 | 4/7/15* | 1 | |||
| 10 111 SSS | CP SSS | A-SSS | SZ*H*V1C | 4/7/15* | 1 | F5 и F3 - копия SSS | ||
| Группа 11 | ||||||||
| 11 CCC 000 | RET CCC | Если CCC то PCL <- [SP] PCH <- [SP+1] SP <- SP+2 | -------- | 11/5 | 1 | |||
| 11 RP0 001 | POP RP | RPH <- [SP] RPL <- [SP+1] SP <- SP+2 | -------- ******** | 10 | 1 | Если RP=3, то подразумевается AF, а не SP | ||
| 11 001 001 | C9 | RET | PCL <- [SP] PCH <- [SP+1] SP <- SP+2 | -------- | 10 | 1 | ||
| 11 011 001 | D9 | EXX | BC,DE,HL <-> BC',DE',HL' | -------- | 4 | 1 | ||
| 11 101 001 | E9 | JP [HL] | PC <- HL | -------- | 4 | 1 | С префиксами становится JP [IX], а не JP [IX+d] | |
| 11 111 001 | F9 | LD SP,HL | SP <- HL | -------- | 6 | 1 | ||
| 11 CCC 010 | nn | JP CCC, [nn] | Если CCC то PC <- nn | -------- | 10 | 3 | ||
| 11 000 011 | C3 | nn | JP nn | PC <- nn | -------- | 10 | 3 | |
| 11 001 011 | CB | Префикс | ||||||
| 11 010 011 | D3 | d | OUT (d),A | [Ad] <- A | -------- | 11 | 2 | Номер порта в реальности 16-разрядный | 
| 11 011 011 | DB | d | IN A, (d) | A <- [Ad] | -------- | 11 | 2 | Номер порта в реальности 16-разрядный | 
| 11 100 011 | E3 | EX (SP),HL | [SP] <-> HL | -------- | 19 | 1 | ||
| 11 101 011 | EB | EX DE,HL | DE <-> HL | -------- | 4 | 1 | Префиксы игнорируются | |
| 11 110 011 | F3 | DI | IFF1 <- 0 IFF2 <- 0 | -------- | 4 | 1 | Запрет прерывания | |
| 11 111 011 | FB | EI | IFF1 <- 1 IFF2 <- 1 | -------- | 4 | 1 | Разрешение прерывания. До завершения следующей команды проверка на INT блокируется (как после NONI) | |
| 11 ССС 100 | nn | CALL ССС, [nn] | Если ССС то SP <- SP-2 [SP] <- PCL [SP+1] <- PCH PC <- nn | -------- | 17/10 | 3 | ||
| 11 RP0 101 | PUSH RP | SP <- SP-2 [SP] <- RPL [SP+1] <- RPH | -------- | 11 | 1 | Если RP=3, то подразумевается AF, а не SP | ||
| 11 001 101 | CD | nn | CALL [nn] | SP <- SP-2 [SP] <- PCL [SP+1] <- PCH PC <- nn | -------- | 17 | 3 | |
| 11 011 101 | DD | Префикс | ||||||
| 11 101 101 | ED | Префикс | ||||||
| 11 111 101 | FD | Префикс | ||||||
| 11 000 110 | C6 | d | ADD A, d | A <- A+d+CY | SZ5H3V0C | 7 | 2 | |
| 11 001 110 | CE | d | ADC A, d | A <- A+d+CY | SZ5H3V0C | 7 | 2 | |
| 11 010 110 | D6 | d | SUB A, d | A <- A-d | SZ5H3V1C | 7 | 2 | |
| 11 011 110 | DE | d | SBC A, d | A <- A-d-CY | SZ5H3V1C | 7 | 2 | |
| 11 100 110 | E6 | d | AND A, d | A <- A AND d | SZ513P00 | 7 | 2 | |
| 11 101 110 | EE | d | XOR A, d | A <- A XOR d | SZ503P00 | 7 | 2 | |
| 11 110 110 | F6 | d | OR A, d | A <- A OR d | SZ503P00 | 7 | 2 | |
| 11 111 110 | FE | d | CP A, d | A-d | SZ*H*V1C | 7 | 2 | F5 и F3 - копия d | 
| 11 NNN 111 | RST NNN | [SP-1] <- PCH [SP-2] <- PCL SP <- SP-2 PCH <- 0 PCL <- NNN*8 | -------- | 11 | 1 | |||
Префикс CB
| Код | Данные | Команда | Действие | Флаги | Такты | Байты | Примечание | |
|---|---|---|---|---|---|---|---|---|
| 2 | 16 | SZ5H3VNC | ||||||
| 11 001 011 00 rot SSS | CB xx | rot SSS *SLL SSS | Битовый сдвиг | SZ503P0C | 8/15* | 2 | rot=110 (SLL) - недок. | |
| 11 001 011 01 bit SSS | CB xx | BIT bit, SSS | SSS AND 2^bit | *Z513*0- | 8/12* | 2 | Установка флагов - см. /BIT | |
| 11 001 011 10 bit SSS | CB xx | RES bit, SSS | SSS <- SSS AND NOT(2^bit) | -------- | 8/15* | 2 | ||
| 11 001 011 11 bit SSS | CB xx | SET bit, SSS | SSS <- SSS OR 2^bit | -------- | 8/15* | 2 | ||
Префикс ED
| Код | Данные | Команда | Действие | Флаги | Такты | Байты | Примечание | |
|---|---|---|---|---|---|---|---|---|
| 2 | 16 | SZ5H3VNC | ||||||
| Группа 00 | ||||||||
| 11 101 101 00 XXX XXX | ED xx | INVALID | NOP/NONI | -------- | 8 | 2 | R увеличивается на 2 (далее аналогично) | |
| Группа 01 | ||||||||
| 11 101 101 01 110 000 | ED 70 | *IN F, [C] | IN[BC] | SZ503P0- | 12? | 2 | Меняются только флаги Номер порта в реальности 16-разрядный | |
| 11 101 101 01 DDD 000 | ED xx | IN DDD, [C] | DDD <- IN[BC] | SZ503P0- | 12 | 2 | DDD кроме 110 | |
| 11 101 101 01 110 001 | ED 71 | *OUT [C], 0 | OUT[BC] <- 0 | -------- | 12 | 2 | ||
| 11 101 101 01 SSS 001 | ED xx | OUT [C], SSS | OUT[BC] <- SSS | -------- | 12 | 2 | SSS кроме 110 Номер порта в реальности 16-разрядный | |
| 11 101 101 01 RP0 010 | ED xx | SBC HL, RP | HL <- HL-RP-C | SZ***V1C | 15 | 2 | См. ADD HL, RP | |
| 11 101 101 01 RP1 010 | ED xx | ADC HL, RP | HL <- HL+RP+C | SZ***V0C | 15 | 2 | См. ADD HL, RP | |
| 11 101 101 01 RP0 011 | ED xx | nn | LD [nn], RP | [nn] <- RP | -------- | 20 | 4 | |
| 11 101 101 01 RP1 011 | ED xx | nn | LD RP, [nn] | RP <- [nn] | -------- | 20 | 4 | |
| 11 101 101 01 XXX 100 | ED 44 | NEG/*NEG | A <- 0-A | SZ5H3V1C | 8 | 2 | XXX<>0 недок PV=1 если перед операцией A=80 С=1 если перед операцией A<>0 | |
| 11 101 101 01 001 101 | ED 4D | RETI | IFF1 <- IFF2 SP <- SP+2 PC <- [SP-2] | -------- | 14 | 2 | Возврат из INT | |
| 11 101 101 01 XXX 101 | ED xx | RETN *RETN | IFF1 <- IFF2 SP <- SP+2 PC <- [SP-2] | -------- | 14 | 2 | Возврат из NMI XXX=1 => RETI XXX>1 недок. | |
| 11 101 101 01 X00 110 | ED 46 | IM 0/*IM 0 | IM <- 0 | -------- | 8 | 2 | X=1 недок | |
| 11 101 101 01 X01 110 | ED 4E | *IM 0/1 | IM <- 0/1? | -------- | 8 | 2 | Устанавливается один из режимов, какой - по одним источникам неизвестно, по другим IM 0 | |
| 11 101 101 01 X10 110 | ED 56 | IM 1/*IM 1 | IM <- 1 | -------- | 8 | 2 | X=1 недок | |
| 11 101 101 01 X11 110 | ED 5E | IM 2/*IM 2 | IM <- 2 | -------- | 8 | 2 | X=1 недок | |
| 11 101 101 01 000 111 | ED 47 | LD I, A | I <- A | -------- | 9 | 2 | ||
| 11 101 101 01 001 111 | ED 4F | LD R, A | R <- A | -------- | 9 | 2 | ||
| 11 101 101 01 010 111 | ED 57 | LD A, I | A <- I PV <- IFF2 | SZ503*0- | 9 | 2 | Известная ошибка: если в момент выполнения команды получено прерывание, то в PV вместо 1 ошибочно попадает 0. Есть программы, которые строят на этом защиту от эмуляции. | |
| 11 101 101 01 011 111 | ED 5F | LD A, R | A <- R PV <- IFF2 | SZ503*0- | 9 | 2 | См. LD A, I Значение в A равно R выполнения инструкции | |
| 11 101 101 01 100 111 | ED 67 | RRD | SZ503P0- | 18 | 2 | Флаги по результату в A | ||
| 11 101 101 01 101 111 | ED 6F | RLD | SZ503P0- | 18 | 2 | См. RRD | ||
| 11 101 101 01 11X 111 | ED xx | NOP | -------- | 8? | 2 | |||
| Группа 10 | ||||||||
| 11 101 101 10 0XX XXX | ED xx | *INVALID | NOP/NONI | -------- | 8 | 2 | ||
| 11 101 101 10 100 000 | ED A0 | LDI | [DE] <- [HL] DE <- DE+1 HL <- HL+1 BC <- BC-1 | --*0**0- | 16 | 2 | PV=1 если после декремента BC<>0 F3=бит 3 операции переданный байт + A F5=бит 1 операции переданный байт + A R увеличивается на 2 (далее аналогично) | |
| 11 101 101 10 100 001 | ED A1 | CPI | A-[HL] HL <- HL+1 BC <- BC-1 | SZ*H**1- | 16 | 2 | PV=1 если после декремента BC<>0 S,Z,HC из A-[HL] F3=бит 3 операции A-[HL]-HC, где HC взят из F после предыдущей операции F5=бит 1 операции A-[HL]-HC | |
| 11 101 101 10 100 010 | ED A2 | INI | [HL] <- IN [BC] HL <- HL+1 B <- B-1 | SZ5*3*** | 16 | 2 | Адрес порта 16-битный из ВС Флаги см. /INI | |
| 11 101 101 10 100 011 | ED A3 | OUTI | OUT [BC] <- [HL] HL <- HL+1 B <- B-1 | SZ5*3*** | 16 | 2 | См. INI | |
| 11 101 101 10 100 1XX | ED xx | *INVALID | NOP/NONI | -------- | 8 | 2 | ||
| 11 101 101 10 101 000 | ED A8 | LDD | [DE] <- [HL] DE <- DE-1 HL <- HL-1 BC <- BC-1 | --*0**0- | 16 | 2 | См. LDI | |
| 11 101 101 10 101 001 | ED A9 | CPD | A-[HL] HL <- HL-1 BC <- BC-1 | SZ*H**1- | 16 | 2 | См. CPI | |
| 11 101 101 10 101 010 | ED AA | IND | [HL] <- IN [BC] HL <- HL-1 B <- B-1 | SZ5*3*** | 16 | 2 | См. INI | |
| 11 101 101 10 101 011 | ED AB | OUTD | OUT [C], [HL] HL <- HL-1 B <- B-1 | SZ5*3*** | 16 | 2 | См. INI | |
| 11 101 101 10 101 1XX | ED xx | *INVALID | NOP/NONI | -------- | 8 | 2 | ||
| 11 101 101 10 110 000 | ED B0 | LDIR | Повторять LDI до BC=0, т.е.: Выполнить LDI Если BC<>0 то PC <- PC-2 | --*0**0- | 21/16** | 2 | См. LDI R увеличивается на 2 каждый цикл? | |
| 11 101 101 10 110 001 | ED B1 | CPIR | Повторять CPI до BC=0 | SZ*H**1- | 21/16** | 2 | См. CPI | |
| 11 101 101 10 110 010 | ED B2 | INIR | Повторять INI до B=0 | SZ5*3*** | 21/16** | 2 | ||
| 11 101 101 10 110 011 | ED B3 | OTIR | Повторять OTI до B=0 | SZ5*3*** | 21/16** | 2 | ||
| 11 101 101 10 110 1XX | ED xx | *INVALID | NOP/NONI | -------- | 8 | 2 | ||
| 11 101 101 10 111 000 | ED B8 | LDDR | Повторять LDD до BC=0 | --*0**0- | 21/16** | 2 | См. LDI | |
| 11 101 101 10 111 001 | ED B9 | CPDR | Повторять CPD до BC=0 | SZ*H**1- | 21/16** | 2 | См. CPI | |
| 11 101 101 10 111 010 | ED BA | INDR | Повторять IND до B=0 | SZ5*3*** | 21/16** | 2 | См. INI | |
| 11 101 101 10 111 011 | ED BB | OTDR | Повторять OTD до B=0 | SZ5*3*** | 21/16** | 2 | См. INI | |
| 11 101 101 10 111 1XX | ED xx | *INVALID | NOP/NONI | -------- | 8 | 2 | ||
| Группа 11 | ||||||||
| 11 101 101 11 XXX XXX | ED xx | *INVALID | NOP/NONI | -------- | 8 | 2 | ||
Префиксы DD и FD
- Для FD IX заменяется на IY
| Код | Данные | Команда | Действие | Флаги | Такты | Байты | Примечание | |
|---|---|---|---|---|---|---|---|---|
| 2 | 16 | SZ5H3VNC | ||||||
| 11 011 101 | DD | NOP/NONI | -------- | 4 | 1 | Префикс игнорируется | ||
| 11 101 101 | ED | NOP/NONI | -------- | 4 | 1 | Префикс игнорируется | ||
| 11 111 101 | FD | NOP/NONI | -------- | 4 | 1 | Префикс игнорируется | ||
| 11 001 011 | CB | Двойной префикс | См. #Префиксы DDCB и FDCB | |||||
| 11 011 101 xx xxx xxx | DD xx | Все однобайтовые команды, использующие HL | HL заменяется на IX | +4 | +1 | Исключение: EX DE, HL | ||
| 11 011 101 xx xxx xxx | DD xx | *Все однобайтовые команды, использующие H | H заменяется на IXH | +4 | +1 | |||
| 11 011 101 xx xxx xxx | DD xx | *Все однобайтовые команды, использующие L | L заменяется на IXL | +4 | +1 | |||
| 11 011 101 xx xxx xxx dd ddd ddd | DD xx dd | Все однобайтовые команды, использующие [HL] | [HL] заменяется на [IX+d] | +2 | H и L без изменений LD H, [HL] => LD H, [IX+d] JP [HL] => JP IX | |||
| Остальные команды | Без изменений | +4 | +1 | R увеличивается на 2, а не на 1 | ||||
Префиксы DDCB и FDCB
- Для FDCB IX заменяется на IY
| Код | Данные | Команда | Действие | Флаги | Такты | Байты | Примечание | |
|---|---|---|---|---|---|---|---|---|
| 2 | 16 | SZ5H3VNC | ||||||
| 11 011 101 11 001 011 dd ddd ddd 00 rot 110 | DD CB dd xx | rot [IX+d] *SLL [IX+d] | Битовый сдвиг байта в памяти | SZ503P0C | 23 | 4 | rot=110 (SLL) - недок. | |
| 11 011 101 11 001 011 dd ddd ddd 00 rot DDD | DD CB dd xx | *LD DDD, rot [IX+d] | Битовый сдвиг байта в памяти и запись результата в регистр | SZ503P0C | 23? | 4 | Результат попадает в регистр даже если он не был записан в память (например, адрес попал на ROM) DDD кроме 110 | |
| 11 011 101 11 001 011 dd ddd ddd 01 bit XXX | DD CB dd xx | BIT bit, [IX+d] *BIT bit, [IX+d] | *Z*1**0- | 20 | 4 | для XXX<>6 недок. P/V, Z и S как в BIT F5 и F3 копии соотв. битов старшего байта адреса IX+d | ||
| 11 011 101 11 001 011 dd ddd ddd 10 bit 110 | DD CB dd xx | RES bit, [IX+d] | Сброс бита [IX+d] <- [IX+d] AND NOT(2^bit) | -------- | 23 | 4 | ||
| 11 011 101 11 001 011 dd ddd ddd 10 bit DDD | DD CB dd xx | *LD DDD, RES bit, [IX+d] | Сброс бита и запись результата в регистр | -------- | 23? | 4 | Результат попадает в регистр даже если он не был записан в память (например, адрес попал на ROM) DDD кроме 110 | |
| 11 011 101 11 001 011 dd ddd ddd 11 bit 110 | DD CB dd xx | SET bit, [IX+d] | Установка бита [IX+d] <- [IX+d] OR 2^bit | -------- | 23 | 4 | ||
| 11 011 101 11 001 011 dd ddd ddd 11 bit DDD | DD CB dd xx | *LD DDD, SET bit, [IX+d] | Установка бита и запись результата в регистр | -------- | 23? | 4 | Результат попадает в регистр даже если он не был записан в память (например, адрес попал на ROM) DDD кроме 110 | |
Внешние сигналы
| Сигнал | Действие | Флаги | Такты | Примечание | 
|---|---|---|---|---|
| NMI | IFF1 <- 0 SP <- SP-2 [SP] <- PC PC <- 0066 | 11 | Вход NMI работает по отрицательному фронту, который запоминается в триггере | |
| INT | Если IFF1=1 IFF1 <- 0 IFF2 <- 0 Если IM=0 Чтение команды с шины данных, выполение Если IM=1 RST 38 Если IM=2 Чтение байта d с шины данных CALL [Id] | IM0: 13 (RST) IM1: 13 IM2: 19 | Вход INT работает по низкому уровню, для возврата к 1 требуется дополнительная логика (определение RETI на шине данных или программное переключение). Проверка INT происходит после выполнения инструкции. Id представляет собой комбинацию старшего байта из регистра I и младшего, полученного по шине. В PC передается значение, взятое из памяти по адресу Id. | |
| RESET | PC <- 0 IFF1 <- 0 IFF2 <- 0 I <- 0 R <- 0 IM <- 0 | 
Пояснения к таблицам
Общие принципы
- Недокументированные команды обозначены звездочкой;
- T=4/7/15* означает, что для регистров время исполнения команды 4 такта, для [HL] — 7, для [IX(IY)+d] — 15. При этом 15 НЕ включает 4 такта выборки префикса, которые должны быть учтены в момент его обработки;
- T=21/17** в блочных операциях означает, что команда выполняется 21 такт при повторении и 17 тактов в последний раз;
- T=17/10 у операторов условного перехода означает, что время исполнения 17 тактов при переходе и 10 без перехода;
- NONI обозначает псевдокоманду, эквивалентную NOP, но после которой не проверяется запрос на прерывание;
- В таблице подразумевается, что в момент исполнения операции PC равен адресу следующей по порядку команды;
- В операциях вида IX+d, d является числом со знаком, в диапазоне −128…+127.
Регистры и флаги
- A, B, C, D, E, H, L — 8-разрядные регистры;
- AF, ВС, DE, HL — регистровые пары;
- PC — указатель текущей команды. PCH и PCL — старший и младший байты, соответственно;
- SP — указатель стека;
- F — Регистр флагов** S: SIGN/Знак. Копия старшего бита результата операции.
- Z: ZERO/Ноль. Равен 1, если результат равен 0.
- *F5: Если не оговорено обратное, равен 5-му биту результата.
- HC: HALF CARRY/Половинный перенос. Обозначает перенос в 4-й бит или заем из него. Используется командой DAA.
- *F3: Если не оговорено обратное, равен 3-му биту результата.
- P/V: PARITY/OVERFLOW/Четность/Переполнение. После одних команд — четность, после других — переполнение. Также копия IFF2 после команд LD A,R и LD A, I
- N: Тип предыдущей операции. 0 — сложение, 1 — вычитание. Используется командой DAA.
- CY: CARRY/Перенос. Обозначает перенос из старшего бита или заем в него.
 
- A`, F`, ВС`, DE`, HL` — второй набор регистров. Переключение между наборами производится командами EX, EXX. При этом установить, какой именно из наборов активен в настоящий момент, невозможно.
- IFF1: Флаг разрешения прерывания;
- IFF2: Флаг, копия IFF1 во время обработки NMI;
- R: Регистр регенерации памяти, 8 бит. Увеличивается на 1 после каждой выборки команды, но инкремент затрагивает только младшие 7 бит, старший бит не меняется и может быть использован в программах.
- При выборке команды с префиксом, R увеличивается еще на 1. В блочных командах R увеличивается на 2 в каждой итерации.
- Для правильной работы LD A, R и LD R, A увеличение R должно происходить до выполнения команды.
- Прием прерывания увеличивает R на единицу.
- Часто используется в программах как генератор случайных чисел.
 
- I: Старший байт адреса вектора прерывания в режиме IM 2;
- IM: Режим обработки прерываний. Устанавливается командами IM 0/1/2.
Расшифровка обозначений
DDD, SSS
| Код2 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 | 
|---|---|---|---|---|---|---|---|---|
| Код10 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 
| Без префикса | B | C | D | E | H | L | [HL] | A | 
| Префикс DD | B | C | D | E | *IXH | *IXL | [IX+d] | A | 
| Префикс FD | B | C | D | E | *IYH | *IYL | [IY+d] | A | 
CCC
| Код2 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 | 
|---|---|---|---|---|---|---|---|---|
| Код10 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 
| Флаг | Z=0 | Z=1 | CY=0 | CY=1 | PV=0 | PV=1 | S=0 | S=1 | 
| Обозначение | NZ | Z | NC | C | PO | PE | P | M | 
| Значение | Не ноль | Ноль | Нет переноса | Перенос | Нечетный Нет переполнения | Четный Переполнение | Положителный | Отрицательный | 
RP
| Код2 | 00 | 01 | 10 | 11 | 
|---|---|---|---|---|
| Код10 | 0 | 1 | 2 | 3 | 
| Без префикса | ВС | DE | HL | SP или AF | 
| Префикс DD | IX или IX+d | |||
| Префикс FD | IY или IY+d | 
rot
| Код2 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 | 
|---|---|---|---|---|---|---|---|---|
| Код10 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 
| Команда | RLC | RRC | RL | RR | SLA | SRA | *SL1 | SRL | 
Особенности выполнения команд
Префиксы
Назначение префикса — модификация поведения следующей за префиксом команды. В Z80 обработка префиксов имеет следующие особенности:
- Считывание префикса занимает 4 такта и добавляет к регистру R единицу. То есть, выполнение команды с префиксом увеличивает R на 2 вместо 1;
- Команды с префиксами CB, ED, DDCB, FDCB удобнее обрабатывать сразу, обратив внимание на поведение регистра R, указанное выше.
- При получении префиксов DD и FD нужно проверить следующий байт:
- Если это DD, FD или ED, то префикс нужно проигнорировать, выполнив команду NONI — 4 такта, прерывания не проверяются. Эффект такого поведения состоит в том, что при наличии длинной цепочки префиксов прерывание (даже NMI) сможет сработать только после ее завершения (точнее, после первой команды, следующей за цепочкой);
- Если следующий байт равен CB, то нужно обработать команду из категории DDCB/FDCB.
 
- Если предыдущий пункт пройден, префиксы DD и FD должны просто установить внутренний флаг замены HL на IX или IY для следующей команды;
- Если модифицированная команда использует адрес вида (IX+d) вместо (HL), то ее длина увеличивается на один дополнительный байт d, а время выполнения - на 8 тактов (плюс, конечно, 4 такта на префикс). Например:
- LD B,C имеет код «41» и занимает 1 байт и 4 такта;
- LD B,(HL) имеет код «46» и занимает 1 байт и 7 тактов;
- LD B,(IX+d) имеет код «DD 46 d» и занимает 3 байта и 19 тактов.(4префикс + 7команда + 8замена (HL)).
 
- Недопустимые команды с префиксом ED должны обрабатываться как NONI на 8 тактов с увеличением R на 2.
Далее приведена таблица команд, на которые влияют префиксы DD и FD (взято из [1]):
+-------------------------------------------------+ | 60 70 | | 21 61 71 E1 | | 22 62 72 | | 23 63 73 E3 | | 24 34 44 54 64 74 84 94 A4 B4 | | 25 35 45 55 65 75 85 95 A5 B5 E5 | | 26 36 46 56 66 86 96 A6 B6 | | 67 77 | | 68 | | 09 19 29 39 69 E9 F9 | | 2A 6A | | 2B 6B CB | | 2C 4C 5C 6C 7C 8C 9C AC BC | | 2D 4D 5D 6D 7D 8D 9D AD BD | | 2E 4E 5E 6E 7E 8E 9E AE BE | | 6F | +-------------------------------------------------+
Команды сдвига
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
Команды ввода-вывода
Хотя в официальной документации написано, что номера портов имеют 8 разрядов, в реальности Z80 формирует 16-разрядный номер порта, и в некоторых компьютерах это используется. Правило следующее:
- IN A, d / OUT d, A — старший байт номера порта берется из A, то есть полный номер — [Ad];
- IN r, C / OUT C, r — старший байт номера порта берется из B, то есть полный номер — [BC];
Расширенные материалы
- /DAA — подробное описание работы команды DAA;
- /BIT — особенности установки недокументированных флагов командой BIT;
- /INI — вычисление флагов в командах блочного ввода-вывода.
Примечания
Ссылки
- Декодирование кодов команд (англ.)
- Таблица команд со временем исполнения (англ.)
- Алфавитный список команд с пояснениями (англ.)
- Действие команд на флаги (англ.)
