-
Notifications
You must be signed in to change notification settings - Fork 10
/
chapter-z80.tex
1028 lines (738 loc) · 52.6 KB
/
chapter-z80.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\chapter{Zilog Z80}
% ██████████████████████████████████████████████████
% █░░░░░░░░░░░░░░░░░░█░░░░░░░░░░░░░░█░░░░░░░░░░░░░░█
% █░░▄▀▄▀▄▀▄▀▄▀▄▀▄▀░░█░░▄▀▄▀▄▀▄▀▄▀░░█░░▄▀▄▀▄▀▄▀▄▀░░█
% █░░░░░░░░░░░░▄▀▄▀░░█░░▄▀░░░░░░▄▀░░█░░▄▀░░░░░░▄▀░░█
% █████████░░░░▄▀░░░░█░░▄▀░░██░░▄▀░░█░░▄▀░░██░░▄▀░░█
% ███████░░░░▄▀░░░░███░░▄▀░░░░░░▄▀░░█░░▄▀░░██░░▄▀░░█
% █████░░░░▄▀░░░░█████░░▄▀▄▀▄▀▄▀▄▀░░█░░▄▀░░██░░▄▀░░█
% ███░░░░▄▀░░░░███████░░▄▀░░░░░░▄▀░░█░░▄▀░░██░░▄▀░░█
% █░░░░▄▀░░░░█████████░░▄▀░░██░░▄▀░░█░░▄▀░░██░░▄▀░░█
% █░░▄▀▄▀░░░░░░░░░░░░█░░▄▀░░░░░░▄▀░░█░░▄▀░░░░░░▄▀░░█
% █░░▄▀▄▀▄▀▄▀▄▀▄▀▄▀░░█░░▄▀▄▀▄▀▄▀▄▀░░█░░▄▀▄▀▄▀▄▀▄▀░░█
% █░░░░░░░░░░░░░░░░░░█░░░░░░░░░░░░░░█░░░░░░░░░░░░░░█
% ██████████████████████████████████████████████████
% TODO
% - Describe BIT A,(HL) undocumented flags from internal MEMPRT/WZ register
% - Add testing code to appendices
\ChapterTOC
% renders two column instruction table; parameters:
% (optional) first column type; defaults to "l"
% (optional) width ratio of the first column; defaults to 0.3
% (required) first column
% (required) second column
% use \TwoColumnInstr to render individual instruction
\NewDocumentCommand{\TwoColumnInstructions}{ O{l} O{0.3} m m }{
{
\tt
\vspace*{1em} % we need some spacing above tables
\begin{parcolumns}[colwidths={1=#2\linewidth}]{2}
\colchunk{
\hspace*{0.25cm} % we want to inset left table inwards
\begin{tabularx}{\linewidth}{#1X}
#3
\end{tabularx}
}
\colchunk{
\begin{tabularx}{\linewidth}{#1X}
#4
\end{tabularx}
}
\end{parcolumns}
}
}
% renders a title inside two column instruction; parameters:
% (required) the title
\newcommand{\TwoColumnTitle}[1]{
\multicolumn{2}{l}{\rm #1} \\
}
% renders single instruction spanning accross whole width; parameters:
% (required) the instruction to render
\newcommand{\TwoColumnSingleInstr}[1]{
\multicolumn{2}{l}{#1} \\
}
% renders individual two column instruction; parameters:
% (required) address
% (required) instruction
\newcommand{\TwoColumnInstr}[2]{
#1 & #2 \\
}
\pagebreak
\section{Overview}
\subsection{History of the Z80}
In 1969 Intel was approached by a Japanese company called Busicom to produce chips for Busicom's electronic desktop calculator. Intel suggested that the calculator should be built around a single-chip generalized computing engine and thus was born the first microprocessor - the 4004. Although it was based on ideas from a much larger mainframe and mini-computers the 4004 was cut down to fit onto a 16-pin chip, the largest that was available at the time, so that its data bus and address bus were each only 4-bits wide.
Intel went on to improve the design and produced the 4040 (an improved 4-bit design) the 8008 (the first 8-bit microprocessor) and then in 1974 the 8080. This last one turned out to be a very useful and popular design and was used in the first home computer, the Altair 8800, and CP/M.
In 1975 Federico Faggin who had worked at Intel on the 4004 and its successors left the company and joined forces with Masatoshi Shima to form Zilog. At their new company, Faggin and Shima designed a microprocessor that was compatible with Intel's 8080 (it ran all 78 instructions of the 8080 in almost the same way that Intel's chip did)\footnote{Thanks to Jim Battle (\email{frustum}{pacbell}{net}): the 8080 always puts the parity in the PF flag; VF does not exist and the timing is different. Possibly there are other differences.} but had many more abilities (an extra 120 instructions, many more registers, simplified connection to hardware). Thus was born the mighty Z80, and thus was the empire forged!
The original Z80 was first released in July 1976, coincidentally Jan was born in the very same month. Since then newer versions have appeared with much of the same architecture but running at higher speeds. The original Z80 ran with a clock rate of 2.5MHz, the Z80A runs at 4MHz, the Z80B at 6MHz and the Z80H at 8Mhz.
Many companies produced machines based around Zilog's improved chip during the 1970s and 80's and because the chip could run 8080 code without needing any changes to the code the perfect choice of the operating system was CP/M.
Also, Zilog has created a Z280, an enhanced version of the Zilog Z80 with a 16-bit architecture, introduced in July 1987. It added an MMU to expand addressing to 16Mb, features for multitasking, a 256-byte cache, and a huge number of new opcodes (giving a total of over 2000!). Its internal clock runs at 2 or 4 times the external clock (e.g. a 16MHz CPU with a 4MHz bus.
The Z380 CPU incorporates advanced architectural while maintaining Z80/Z180 object code compatibility. The Z380 CPU is an enhanced version of the Z80 CPU. The Z80 instruction set has been retained, adding a full complement of 16-bit arithmetic and logical operations, multiply and divide, a complete set of register-to-register loads and exchanges, plus 32-bit load and exchange, and 32-bit arithmetic operations for address calculations.
The addressing modes of the Z80 have been enhanced with Stack pointer relative loads and stores, 16-bit and 24-bit indexed offsets and more flexible indirect register addressing. All of the addressing modes allow access to the entire 32-bit addressing space.
\subsection{Pin Descriptions \cite{datasheet}}
\label{z80_pin_descriptions}
This section might be relevant even if you don't do anything with hardware; it might give you insight into how the Z80 operates. Besides, it took me hours to draw this.
{\tt
\setlength{\unitlength}{1mm}
\begin{picture}(50,80)
\multiput(11.8,2)(0,3.9){20}{\framebox(2,2){}}
\multiput(36.2,2)(0,3.9){20}{\framebox(2,2){}}
\thicklines \footnotesize
\put(14,0){\framebox(22,80){Z80 CPU}}
\put(25,80){\oval(3,3)[b]}
\thinlines
\newcounter{pinno}
\multiput(15,76)(0,-3.9){20}{\stepcounter{pinno}\makebox(2,2){\arabic{pinno}}}
\multiput(33,2)(0,3.9){20}{\stepcounter{pinno}\makebox(2,2)[r]{\arabic{pinno}}}
\put(9,2){\makebox(2,2)[r]{\NoLinkChipPinLabel{IORQ}}}
\put(9,5.9){\makebox(2,2)[r]{\NoLinkChipPinLabel{MREQ}}}
\put(9,9.8){\makebox(2,2)[r]{\NoLinkChipPinLabel{HALT}}}
\put(9,13.7){\makebox(2,2)[r]{\NoLinkChipPinLabel{NMI}}}
\put(9,17.6){\makebox(2,2)[r]{\NoLinkChipPinLabel{INT}}}
\put(9,21.5){\makebox(2,2)[r]{$\mathtt{D_1}$}}
\put(9,25.4){\makebox(2,2)[r]{$\mathtt{D_0}$}}
\put(9,29.3){\makebox(2,2)[r]{$\mathtt{D_7}$}}
\put(9,33.2){\makebox(2,2)[r]{$\mathtt{D_2}$}}
\put(9,37.1){\makebox(2,2)[r]{$\mathtt{+ 5V}$}}
\put(9,41){\makebox(2,2)[r]{$\mathtt{D_6}$}}
\put(9,44.9){\makebox(2,2)[r]{$\mathtt{D_5}$}}
\put(9,48.8){\makebox(2,2)[r]{$\mathtt{D_3}$}}
\put(9,52.7){\makebox(2,2)[r]{$\mathtt{D_4}$}}
\put(9,56.6){\makebox(2,2)[r]{$\mathtt{CLK}$}}
\put(9,60.5){\makebox(2,2)[r]{$\mathtt{A_{15}}$}}
\put(9,64.4){\makebox(2,2)[r]{$\mathtt{A_{14}}$}}
\put(9,68.3){\makebox(2,2)[r]{$\mathtt{A_{13}}$}}
\put(9,72.2){\makebox(2,2)[r]{$\mathtt{A_{12}}$}}
\put(9,76.1){\makebox(2,2)[r]{$\mathtt{A_{11}}$}}
\put(39,2){\makebox(2,2)[l]{\NoLinkChipPinLabel{RD}}}
\put(39,5.9){\makebox(2,2)[l]{\NoLinkChipPinLabel{WR}}}
\put(39,9.8){\makebox(2,2)[l]{\NoLinkChipPinLabel{BUSACK}}}
\put(39,13.7){\makebox(2,2)[l]{\NoLinkChipPinLabel{WAIT}}}
\put(39,17.6){\makebox(2,2)[l]{\NoLinkChipPinLabel{BUSREQ}}}
\put(39,21.5){\makebox(2,2)[l]{\NoLinkChipPinLabel{RESET}}}
\put(39,25.4){\makebox(2,2)[l]{\NoLinkChipPinLabel{M1}}}
\put(39,29.3){\makebox(2,2)[l]{\NoLinkChipPinLabel{RFSH}}}
\put(39,33.2){\makebox(2,2)[l]{$\mathtt{GND}$}}
\put(39,37.1){\makebox(2,2)[l]{$\mathtt{A_0}$}}
\put(39,41.0){\makebox(2,2)[l]{$\mathtt{A_1}$}}
\put(39,44.9){\makebox(2,2)[l]{$\mathtt{A_2}$}}
\put(39,48.8){\makebox(2,2)[l]{$\mathtt{A_3}$}}
\put(39,52.7){\makebox(2,2)[l]{$\mathtt{A_4}$}}
\put(39,56.6){\makebox(2,2)[l]{$\mathtt{A_5}$}}
\put(39,60.5){\makebox(2,2)[l]{$\mathtt{A_{6}}$}}
\put(39,64.4){\makebox(2,2)[l]{$\mathtt{A_{7}}$}}
\put(39,68.3){\makebox(2,2)[l]{$\mathtt{A_{8}}$}}
\put(39,72.2){\makebox(2,2)[l]{$\mathtt{A_{9}}$}}
\put(39,76.1){\makebox(2,2)[l]{$\mathtt{A_{10}}$}}
\end{picture}
}
\begin{description}[leftmargin=1.5em]
\item[$A_{15}$-${A_0}$]
{\em Address bus} (output, active high, 3-state). This bus is used for accessing the memory and for I/O ports. During the refresh cycle the IR register is put on this bus.
\item[\NoLinkChipPinLabel{BUSACK}]
{\em Bus Acknowledge} (output, active low). Bus Acknowledge indicates to the requesting device that the CPU address bus, data bus, and control signals \NoLinkChipPinLabel{MREQ}, \NoLinkChipPinLabel{IORQ}, \NoLinkChipPinLabel{RD} and \NoLinkChipPinLabel{WR} have been entered into their high-impedance states. The external device now control these lines.
\item[\NoLinkChipPinLabel{BUSREQ}]
{\em Bus Request} (input, active low). Bus Request has a higher priority than \NoLinkChipPinLabel{NMI} and is always recognised at the end of the current machine cycle. \NoLinkChipPinLabel{BUSREQ} forces the CPU address bus, data bus and control signals \NoLinkChipPinLabel{MREQ}, \NoLinkChipPinLabel{IORQ}, \NoLinkChipPinLabel{RD} and \NoLinkChipPinLabel{WR} to go to a high-impedance state so that other devices can control these lines. \NoLinkChipPinLabel{BUSREQ} is normally wired-OR and requires an external pullup for these applications. Extended \NoLinkChipPinLabel{BUSREQ} periods due to extensive DMA operations can prevent the CPU from refreshing dynamic RAMs.
\item[${D_7}$-${D_0}$]
{\em Data Bus} (input/output, active low, 3-state). Used for data exchanges with memory, I/O and interrupts.
\item[\NoLinkChipPinLabel{HALT}]
{\em Halt State} (output, active low). Indicates that the CPU has executed a {\tt HALT} instruction and is waiting for either a maskable or nonmaskable interrupt (with the mask enabled) before operation can resume. While halted, the CPU stops increasing the PC so the instruction is re-executed, to maintain memory refresh.
\item[\NoLinkChipPinLabel{INT}]
{\em Interrupt Request} (input, active low). Interrupt Request is generated by I/O devices. The CPU honours a request at the end of the current instruction if {\tt IFF1} is set. \NoLinkChipPinLabel{INT} is normally wired-OR and requires an external pullup for these applications.
\item[\NoLinkChipPinLabel{IORQ}]
{\em Input/Output Request} (output, active low, 3-state). Indicates that the address bus holds a valid I/O address for an I/O read or write operation. \NoLinkChipPinLabel{IORQ} is also generated concurrently with \NoLinkChipPinLabel{M1} during an interrupt acknowledge cycle to indicate that an interrupt response vector can be placed on the databus.
\item[\NoLinkChipPinLabel{M1}]
{\em Machine Cycle One} (output, active low). \NoLinkChipPinLabel{M1}, together with \NoLinkChipPinLabel{MREQ}, indicates that the current machine cycle is the opcode fetch cycle of an instruction execution. \NoLinkChipPinLabel{M1}, together with \NoLinkChipPinLabel{IORQ}, indicates an interrupt acknowledge cycle.
\item[\NoLinkChipPinLabel{MREQ}]
{\em Memory Request} (output, active low, 3-state). Indicates that the address holds a valid address for a memory read or write cycle operations.
\item[\NoLinkChipPinLabel{NMI}]
{\em Non-Maskable Interrupt} (input, negative edge-triggered). \NoLinkChipPinLabel{NMI} has a higher priority than \NoLinkChipPinLabel{INT}. \NoLinkChipPinLabel{NMI} is always recognised at the end of an instruction, independent of the status of the interrupt flip-flops and automatically forces the CPU to restart at location \$0066.
\item[\NoLinkChipPinLabel{RD}]
{\em Read} (output, active low, 3-state). Indicates that the CPU wants to read data from memory or an I/O device. The addressed I/O device or memory should use this signal to place data onto the data bus.
\item[\NoLinkChipPinLabel{RESET}]
{\em Reset} (input, active low). Initializes the CPU as follows: it resets the interrupt flip-flops, clears the PC and IR registers, and set the interrupt mode to 0. During reset time, the address bus and data bus go to a high-impedance state, and all control output signals go to the inactive state. Note that \NoLinkChipPinLabel{RESET} must be active for a minimum of three full clock cycles before the reset operation is complete. Note that Matt found that SP and AF are set to \$FFFF.
\item[\NoLinkChipPinLabel{RFSH}]
{\em Refresh} (output, active low). \NoLinkChipPinLabel{RFSH}, together with \NoLinkChipPinLabel{MREQ}, indicates that the IR registers are on the address bus (note that only the lower 7 bits are useful) and can be used for the refresh of dynamic memories.
\item[\NoLinkChipPinLabel{WAIT}]
{\em Wait} (input, active low). Indicates to the CPU that the addressed memory or I/O device are not ready for data transfer. The CPU continues to enter a wait state as long as this signal is active. Note that during this period memory is not refreshed.
\item[\NoLinkChipPinLabel{WR}]
{\em Write} (output, active low, 3-state). Indicates that the CPU wants to write data to memory or an I/O device. The addressed I/O device or memory should use this signal to store the data on the data bus.
\end{description}
\subsection{Power on Defaults}
\label{z80_power_on_defaults}
Matt\footnote{\email{redflame}{xmission}{com}} has done some excellent research on this. He found that AF and SP are always set to \MemAddr{FFFF} after a reset, and all other registers are undefined (different depending on how long the CPU has been powered off, different for different Z80 chips). Of course, the PC should be set to 0 after a reset, and so should the {\tt IFF1} and {\tt IFF2} flags (otherwise strange things could happen). Also since the Z80 is 8080 compatible, the interrupt mode is probably 0.
Probably the best way to simulate this in an emulator is to set {\tt PC}, {\tt IFF1}, {\tt IFF2}, {\tt IM} to 0 and set all other registers to \MemAddr{FFFF}.
\subsection{Registers}
\begin{tikzpicture}[
framed/.style={draw, font=\ttfamily, minimum width=1.1cm, minimum height=0.5cm},
filled/.style={framed, fill=PrintableLightGray},
frameddouble/.style={framed, minimum width=2.2cm},
filleddouble/.style={filled, minimum width=2.2cm},
desc/.style={midway,xshift=1.5ex,anchor=west},
curly/.style={
decorate,
decoration={brace,amplitude=5pt,raise=3pt},
line width=1pt,
yshift=0pt,
shorten >=1pt,
shorten <=1pt
}
]
\node[framed] (a) {A};
\node[framed, right=0pt of a] (f) {F};
\draw[curly] (f.north east) -- (f.south east) node[desc] {Accumulator and Flags};
\node[filleddouble, below=0pt of a.south east] (bc) {BC};
\node[filleddouble, below=0pt of bc] (de) {DE};
\node[filleddouble, below=0pt of de] (hl) {HL};
\draw[curly] (bc.north east) -- (hl.south east) node[desc] {General purpose registers};
\node[frameddouble, below=0pt of hl] (ix) {IX};
\node[frameddouble, below=0pt of ix] (iy) {IY};
\draw[curly] (ix.north east) -- (iy.south east) node[desc] {Index registers};
\node[filleddouble, below=0pt of iy] (pc) {PC};
\node[filleddouble, below=0pt of pc] (sp) {SP};
\node[filled, below=0pt of sp.south west, anchor=north west] (i) {I};
\node[filled, right=0pt of i] (r) {R};
\draw[curly] (pc.north east) -- (r.south east) node[desc] {Special purpose registers};
\node[frameddouble, below=0pt of i.south east] (afe) {AF'};
\node[frameddouble, below=0pt of afe] (bce) {BC'};
\node[frameddouble, below=0pt of bce] (dee) {DE'};
\node[frameddouble, below=0pt of dee] (hle) {HL'};
\draw[curly] (afe.north east) -- (hle.south east) node[desc] {Alternate general purpose registers};
\end{tikzpicture}
\subsection{Flags}
\label{z80_flags}
The conventional way of denoting the flags is with one letter, ``C'' for the carry flag for example. It could be confused with the C register, so I've chosen to use the ``CF'' notation for flags (except ``P'' which uses ``PV'' notation due to having dual-purpose, either as parity or overflow). And for YF and XF the same notation is used in MAME\footnote{\url{http://www.mame.net/}}.
\begin{tabular}{|l|c|c|c|c|c|c|c|c|}
\hline
bit & 7 & 6 & 5 & 4 & 3 & 2 & 1 & 0 \instrt\instrb \\
\hline
flag & SF & ZF & YF & HF & XF & PF & NF & CF \instrt\instrb \\
\hline
\end{tabular}
\begin{description}
\item[SF]
Set if the 2-complement value is negative; simply a copy of the most significant bit.
\item[ZF]
Set if the result is zero.
\item[YF]
A copy of bit 5 of the result.
\item[HF]
The half-carry of an addition/subtraction (from bit 3 to 4). Needed for BCD correction with {\tt DAA}.
\item[XF]
A copy of bit 3 of the result.
\item[PV]
This flag can either be the parity of the result (PF), or the 2-complement signed overflow (VF): set if 2-complement value doesn't fit in the register.
\item[NF]
Shows whether the last operation was an addition (0) or a subtraction (1). This information is needed for {\tt DAA}.\footnote{Wouldn't it be better to have separate instructions for {\tt DAA} after addition and subtraction, like the 80x86 has instead of sacrificing a bit in the flag register?}
\item[CF]
The carry flag, set if there was a carry after the most significant bit.
\end{description}
\section{Undocumented Opcodes}
There are quite a few undocumented opcodes/instructions. This section should describe every possible opcode so you know what will be executed, whatever the value of the opcode is.
The following prefixes exist: {\tt CB}, {\tt ED}, {\tt DD}, {\tt FD}, {\tt DDCB} and {\tt FDCB}. Prefixes change the way the following opcodes are interpreted. All instructions without a prefix (not a value of one the above) are single-byte opcodes (without the operand, that is), which are documented in the official documentation.
\subsection{CB Prefix \cite{gerton}}
\label{z80_undocumented_prefix_cb}
An opcode with a {\tt CB} prefix is a rotate, shift or bit test/set/reset instruction. A few instructions are missing from the official list, for example {\tt SLL} (Shift Logical Left). It works like {\tt SLA}, for one exception: it sets bit 0 ({\tt SLA} resets it).
\TwoColumnInstructions{
\TwoColumnInstr{CB30}{SLL B}
\TwoColumnInstr{CB31}{SLL C}
\TwoColumnInstr{CB32}{SLL D}
\TwoColumnInstr{CB33}{SLL E}
}{
\TwoColumnInstr{CB34}{SLL H}
\TwoColumnInstr{CB35}{SLL L}
\TwoColumnInstr{CB36}{SLL (HL)}
\TwoColumnInstr{CB37}{SLL A}
}
\subsection{DD Prefix \cite{gerton}}
In general, the instruction following the {\tt DD} prefix is executed as is, but if the {\tt HL} register is supposed to be used the {\tt IX} register is used instead. Here are the rules:
\begin{itemize}[topsep=1pt,itemsep=1pt]
\item Any usage of {\tt HL} is treated as an access to {\tt IX} (except {\tt EX DE,HL} and {\tt EXX} and the {\tt ED} prefixed instructions that use {\tt HL}).
\item Any access to {\tt (HL)} is changed to {\tt (IX+d)}, where ``d'' is a signed displacement byte placed after the main opcode - except {\tt JP (HL)}, which isn't indirect anyway. The mnemonic should be {\tt JP HL}.
\item Any access to {\tt H} is treated as an access to {\tt IX\High} (the high byte of {\tt IX}) except if {\tt (IX+d)} is used as well.
\item Any access to {\tt L} is treated as an access to {\tt IX\Low} (the low byte of {\tt IX}) except if {\tt (IX+d)} is used as well.
\item A {\tt DD} prefix before a {\tt CB} selects a completely different instruction set, see section {\XRef{z80_undocumented_prefix_cbdd}}.
\end{itemize}
Some examples:
\TwoColumnInstructions[p{2.3cm}][0.4]{
\TwoColumnInstr{\rm Without}{\rm With {\tt DD} prefix}
\TwoColumnInstr{LD H, (HL)}{LD H, (IX+d)}
\TwoColumnInstr{LD H, A}{LD IXH, A}
\TwoColumnInstr{LD L, H}{LD IXL, IXH}
}{
\TwoColumnInstr{\rm Without}{\rm With {\tt DD} prefix}
\TwoColumnInstr{JP (HL)}{JP (IX)}
\TwoColumnInstr{LD DE, 0}{LD DE, 0}
\TwoColumnInstr{LD HL, 0}{LD IX, 0}
}
\subsection{ED Prefix \cite{gerton}}
There are a number of undocumented {\tt EDxx} instructions, of which most are duplicates of documented instructions. Any instruction not listed here has no effect (same as 2 {\tt NOP}s). \See{**} indicates undocumented instruction:
\TwoColumnInstructions{
\TwoColumnInstr{ED40}{IN B, (C)}
\TwoColumnInstr{ED41}{OUT (C), B}
\TwoColumnInstr{ED42}{SBC HL, BC}
\TwoColumnInstr{ED43}{LD (nn), BC}
\TwoColumnInstr{ED44}{NEG}
\TwoColumnInstr{ED45}{RETN}
\TwoColumnInstr{ED46}{IM 0}
\TwoColumnInstr{ED47}{LD I, A}
\TwoColumnInstr{ED48}{IN C, (C)}
\TwoColumnInstr{ED49}{OUT (C), C}
\TwoColumnInstr{ED4A}{ADC HL, BC}
\TwoColumnInstr{ED4B}{LD BC, (nn)}
\TwoColumnInstr{ED4C}{NEG\See{**}}
\TwoColumnInstr{ED4D}{RETI}
\TwoColumnInstr{ED4E}{IM 0\See{**}}
\TwoColumnInstr{ED4F}{LD R, A}
}{
\TwoColumnInstr{ED50}{IN D, (C)}
\TwoColumnInstr{ED51}{OUT (C), D}
\TwoColumnInstr{ED52}{SBC HL, DE}
\TwoColumnInstr{ED53}{LD (nn), DE}
\TwoColumnInstr{ED54}{NEG\See{**}}
\TwoColumnInstr{ED55}{RETN\See{**}}
\TwoColumnInstr{ED56}{IM 1}
\TwoColumnInstr{ED57}{LD A, I}
\TwoColumnInstr{ED58}{IN E, (C)}
\TwoColumnInstr{ED59}{OUT (C), E}
\TwoColumnInstr{ED5A}{ADC HL, DE}
\TwoColumnInstr{ED5B}{LD DE, (nn)}
\TwoColumnInstr{ED5C}{NEG\See{**}}
\TwoColumnInstr{ED5D}{RETN\See{**}}
\TwoColumnInstr{ED5E}{IM 2}
\TwoColumnInstr{ED5F}{LD A, R}
}
\TwoColumnInstructions{
\TwoColumnInstr{ED60}{IN H, (C)}
\TwoColumnInstr{ED61}{OUT (C), H}
\TwoColumnInstr{ED62}{SBC HL, HL}
\TwoColumnInstr{ED63}{LD (nn), HL}
\TwoColumnInstr{ED64}{NEG\See{**}}
\TwoColumnInstr{ED65}{RETN\See{**}}
\TwoColumnInstr{ED66}{IM 0\See{**}}
\TwoColumnInstr{ED67}{RRD}
\TwoColumnInstr{ED68}{IN L, (C)}
\TwoColumnInstr{ED69}{OUT (C), L}
\TwoColumnInstr{ED6A}{ADC HL, HL}
\TwoColumnInstr{ED6B}{LD HL, (nn)}
\TwoColumnInstr{ED6C}{NEG\See{**}}
\TwoColumnInstr{ED6D}{RETN\See{**}}
\TwoColumnInstr{ED6E}{IM 0\See{**}}
\TwoColumnInstr{ED6F}{RLD}
}{
\TwoColumnInstr{ED70}{IN (C) / IN F, (C)\See{**}}
\TwoColumnInstr{ED71}{OUT (C), 0\See{**}}
\TwoColumnInstr{ED72}{SBC HL, SP}
\TwoColumnInstr{ED73}{LD (nn), SP}
\TwoColumnInstr{ED74}{NEG\See{**}}
\TwoColumnInstr{ED75}{RETN\See{**}}
\TwoColumnInstr{ED76}{IM 1\See{**}}
\TwoColumnInstr{ED77}{NOP\See{**}}
\TwoColumnInstr{ED78}{IN A, (C)}
\TwoColumnInstr{ED79}{OUT (C), A}
\TwoColumnInstr{ED7A}{ADC HL, SP}
\TwoColumnInstr{ED7B}{LD SP, (nn)}
\TwoColumnInstr{ED7C}{NEG\See{**}}
\TwoColumnInstr{ED7D}{RETN\See{**}}
\TwoColumnInstr{ED7E}{IM 2\See{**}}
\TwoColumnInstr{ED7F}{NOP\See{**}}
}
The {\tt ED70} instruction reads from I/O port {\tt C}, but does not store the result. It just affects the flags like the other {\tt IN x,(C)} instructions. {\tt ED71} simply outs the value 0 to I/O port {\tt C}.
The {\tt ED63} is a duplicate of the 22 opcode ({\tt LD (nn),HL}) and similarly {\tt ED6B} is a duplicate of the {\tt 2A} opcode ({\tt LD HL,(nn)}). Of course the timings are different. These instructions are listed in the official documentation.
\pagebreak
According to Gerton Lunter\footnote{\email{gerton}{math.rug}{nl}}:
\begin{quote}
The instructions {\tt ED 4E} and {\tt ED 6E} are {\tt IM 0} equivalents: when {\tt FF} was put on the bus (physically) at interrupt time, the Spectrum continued to execute normally, whereas when an {\tt EF} ({\tt RST \$28}) was put on the bus it crashed, just as it does in that case when the Z80 is in the official interrupt mode 0. In {\tt IM 1} the Z80 just executes a {\tt RST \$38} (opcode {\tt FF}) no matter what is on the bus.
\end{quote}
All the {\tt RETI/RETN} instructions are the same, all like the {\tt RETN} instruction. So they all, including {\tt RETI}, copy {\tt IFF2} to {\tt IFF1}. See section \XRef{z80_interrupts_flipflop} for more information on {\tt RETI} and {\tt RETN} and {\tt IM x}.
\subsection{FD Prefix \cite{gerton}}
This prefix has the same effect as the {\tt DD} prefix, though {\tt IY} is used instead of {\tt IX}. Note {\tt LD IXL}, {\tt IYH} is not possible: only {\tt IX} or {\tt IY} is accessed in one instruction, never both.
\subsection{DDCB Prefix}
\label{z80_undocumented_prefix_cbdd}
The undocumented {\tt DDCB} instructions store the result (if any) of the operation in one of the seven all-purpose registers. Which one depends on the lower 3 bits of the last byte of the opcode (not operand, so not the offset).
\TwoColumnInstructions{
\TwoColumnInstr{000}{B}
\TwoColumnInstr{001}{C}
\TwoColumnInstr{010}{D}
\TwoColumnInstr{011}{E}
}{
\TwoColumnInstr{100}{H}
\TwoColumnInstr{101}{L}
\TwoColumnInstr{110}{\normalfont{(none: documented opcode)}}
\TwoColumnInstr{111}{A}
}
The documented {\tt DDCB0106} is {\tt RLC (IX+\$01)}. So, clear the lower three bits ({\tt DDCB0100}) and something is done to register {\tt B}. The result of the {\tt RLC} (which is stored in {\tt (IX+\$01)}) is now also stored in register {\tt B}. Effectively, it does the following:
\begin{tcblisting}{}
LD B, (IX+&01)
RLC B
LD (IX+&01), B
\end{tcblisting}
So you get double value for money. The result is stored in {\tt B} and {\tt (IX+\$01)}. The most common notation is: {\tt RLC (IX+\$01), B}
I've once seen this notation:
\begin{tcblisting}{}
RLC (IX+&01)
LD B, (IX+&01)
\end{tcblisting}
That's not correct: {\tt B} contains the rotated value, even if {\tt (IX+\$01)} points to ROM.
The {\tt DDCB} {\tt SET} and {\tt RES} instructions do the same thing as the shift/rotate instructions:
\TwoColumnInstructions[p{2.2cm}][0.9]{
\TwoColumnInstr{DDCB10C0}{SET 0, (IX+\$10), B}
\TwoColumnInstr{DDCB10C1}{SET 0, (IX+\$10), C}
\TwoColumnInstr{DDCB10C2}{SET 0, (IX+\$10), D}
\TwoColumnInstr{DDCB10C3}{SET 0, (IX+\$10), E}
\TwoColumnInstr{DDCB10C4}{SET 0, (IX+\$10), H}
\TwoColumnInstr{DDCB10C5}{SET 0, (IX+\$10), L}
\TwoColumnInstr{DDCB10C6}{SET 0, (IX+\$10) {\rm - documented instruction}}
\TwoColumnInstr{DDCB10C7}{SET 0, (IX+\$10), A}
}{}
So for example with the last instruction, the value of {\tt (IX+\$10)} with bit 0 set is also stored in register {\tt A}.
The {\tt DDCB} {\tt BIT} instructions do not store any value; they merely test a bit. That's why the undocumented {\tt DDCB} {\tt BIT} instructions are no different from the official ones:
\TwoColumnInstructions[p{2.2cm}][0.9]{
\TwoColumnInstr{DDCB d 78}{BIT 7, (IX+d)}
\TwoColumnInstr{DDCB d 79}{BIT 7, (IX+d)}
\TwoColumnInstr{DDCB d 7A}{BIT 7, (IX+d)}
\TwoColumnInstr{DDCB d 7B}{BIT 7, (IX+d)}
\TwoColumnInstr{DDCB d 7C}{BIT 7, (IX+d)}
\TwoColumnInstr{DDCB d 7D}{BIT 7, (IX+d)}
\TwoColumnInstr{DDCB d 7E}{BIT 7, (IX+d) {\rm - documented instruction}}
\TwoColumnInstr{DDCB d 7F}{BIT 7, (IX+d)}
}{}
\subsection{FDCB Prefixes}
Same as for the {\tt DDCB} prefix, though {\tt IY} is used instead of {\tt IX}.
\subsection{Combinations of Prefixes}
This part may be of some interest to emulator coders. Here we define what happens if strange sequences of prefixes appear in the instruction cycle of the Z80.
If {\tt CB} or {\tt ED} is encountered, that byte plus the next make up an instruction. {\tt FD} or {\tt DD} should be seen as prefix setting a flag which says ``use {\tt IX} or {\tt IY} instead of {\tt HL}'', and not an instruction. In a large sequence of {\tt DD} and {\tt FD} bytes, it is the last one that counts. Also any other byte (or instruction) resets this flag.
{\tt {\qquad}FD DD 00 21 00 10{\qquad}NOP NOP NOP LD HL, \$1000}
\section{Undocumented Effects}
\subsection{BIT Instructions}
\label{z80_undocumented_flags_bit}
{\tt BIT n,r} behaves much like {\tt AND r,2{\raisebox{1ex}{n}}} with the result thrown away, and CF flag unaffected. Compare {\tt BIT 7,A} with {\tt AND \$80}: flag YF and XF are reset, SF is set if bit 7 was actually set; ZF is set if the result was 0 (bit was reset), and PV is effectively set if ZF is set (the result of the AND leaves either no bits set (PV set - parity even) or one bit set (PV reset - parity odd). So the rules for the flags are:
\begin{description}
\item[SF flag]
Set if n = 7 and tested bit is set.
\item[ZF flag]
Set if the tested bit is reset.
\item[YF flag]
Set if n = 5 and tested bit is set.
\item[HF flag]
Always set.
\item[XF flag]
Set if n = 3 and tested bit is set.
\item[PV flag]
Set just like ZF flag.
\item[NF flag]
Always reset.
\item[CF flag]
Unchanged.
\end{description}
This is where things start to get strange. With the {\tt BIT n,(IX+d)} instructions, the flags behave just like the {\tt BIT n,r} instruction, except for YF and XF. These are not copied from the result but from something completely different, namely bit 5 and 3 of the high byte of {\tt IX+d} (so {\tt IX} plus the displacement).
Things get more bizarre with the {\tt BIT n,(HL)} instruction. Again, except for YF and XF, the flags are the same. YF and XF are copied from some sort of internal register. This register is related to 16-bit additions. Most instructions do not change this register. Unfortunately, I haven't tested all instructions yet, but here is the list so far:
\begin{tabularx}{\linewidth}{@{}lX}
{\tt ADD HL, xx}
& Use high byte of {\tt HL}, ie. {\tt H} before the addition. \\
{\tt LD r, (IX+d)}
& Use high byte of the resulting address {\tt IX+d}. \\
{\tt JR d}
& Use high byte target address of the jump. \\
{\tt LD r, r'}
& Doesn't change this register. \\
\end{tabularx}
Any help here would be most appreciated!
\pagebreak
\subsection{Memory Block Instructions \cite{mrison}}
\label{z80_undocumented_instructions_memory_block}
The {\tt LDI}/{\tt LDIR}/{\tt LDD}/{\tt LDDR} instructions affect the flags in a strange way. At every iteration, a byte is copied. Take that byte and add the value of register {\tt A} to it. Call that value {\tt n}. Now, the flags are:
\begin{description}
\item[YF flag]
A copy of bit 1 of n.
\item[HF flag]
Always reset.
\item[XF flag]
A copy of bit 3 of n.
\item[PV flag]
Set if BC not 0.
\item[SF, ZF, CF flags]
These flags are unchanged.
\end{description}
And now for {\tt CPI}/{\tt CPIR}/{\tt CPD}/{\tt CPDR}. These instructions compare a series of bytes in memory to register {\tt A}. Effectively, it can be said they perform {\tt CP (HL)} at every iteration. The result of that comparison sets the HF flag, which is important for the next step. Take the value of register {\tt A}, subtract the value of the memory address, and finally subtract the value of HF flag, which is set or reset by the hypothetical {\tt CP (HL)}. So, {\tt n=A-(HL)-HF}.
\begin{description}
\item[SF, ZF, HF flags]
Set by the hypothetical {\tt CP (HL)}.
\item[YF flag]
A copy of bit 1 of {\tt n}.
\item[XF flag]
A copy of bit 3 of {\tt n}.
\item[PV flag]
Set if BC is not 0.
\item[NF flag]
Always set.
\item[CF flag]
Unchanged.
\end{description}
\subsection{I/O Block Instructions}
\label{z80_undocumented_instructions_io_block}
These are the most bizarre instructions, as far as the flags are concerned. Ramsoft found all of the flags. The ``out'' instructions behave differently than the ``in'' instructions, which doesn't make the CPU very symmetrical.
First of all, all instructions affect the following flags:
\begin{description}
\item[SF, ZF, YF, XF flags]
Affected by decreasing register B, as in {\tt DEC B}.
\item[NF flag]
A copy of bit 7 of the value read from or written to an I/O port.
\end{description}
\pagebreak % we want to keep this paragraph with description below to avoid page flipping
And now the for {\tt OUTI}/{\tt OTIR}/{\tt OUTD}/{\tt OTDR} instructions. Take the state of the {\tt L} after the increment or decrement of HL; add the value written to the I/O port; call that {\tt k} for now. If {\tt k} $>$ 255, then the CF and HF flags are set. The PV flag is set like the parity of {\tt k} bitwise and'ed with 7, bitwise xor'ed with {\tt B}.
\begin{description}
\item[HF and CF]
Both set if {\tt ((HL) + L $>$ 255)}
\item[PV]
The parity of {\tt ((((HL) + L) $\wedge$ 7) $\veebar$ B)}
\end{description}
{\tt INI}/{\tt INIR}/{\tt IND}/{\tt INDR} use the {\tt C} register instead of the {\tt L} register. There is a catch though, because not the value of {\tt C} is used, but {\tt C + 1} if it's {\tt INI}/{\tt INIR} or {\tt C - 1} if it's {\tt IND}/{\tt INDR}. So, first of all {\tt INI}/{\tt INIR}:
\begin{description}
\item[HF and CF]
Both set if {\tt ((HL) + ((C + 1) $\wedge$ 255) $\veebar$ 255)}
\item[PF]
The parity of {\tt (((HL) + ((C + 1) $\wedge$ 255)) $\wedge$ 7) $\veebar$ B)}
\end{description}
And last {\tt IND}/{\tt INDR}:
\begin{description}
\item[HF and CF]
Both set if {\tt ((HL) + ((C - 1) $\wedge$ 255) $>$ 255)}
\item[PF]
The parity of {\tt (((HL) + ((C - 1) $\wedge$ 255)) $\wedge$ 7) $\veebar$ B)}
\end{description}
\subsection{16 Bit I/O ports}
Officially the Z80 has an 8-bit I/O port address space. When using the I/O ports, the 16 address lines are used. And in fact, the high 8 bits do have some value, so you can use 65536 ports after all. {\tt IN r, (C)}, {\tt OUT (C), r}, and the block I/O instructions actually place the entire {\tt BC} register on the address bus. Similarly {\tt IN A, (n)} and {\tt OUT (n), A} put {\tt A $\times$256 + n} on the address bus.
The {\tt INI}, {\tt INIR}, {\tt IND} and {\tt INDR} instructions use {\tt BC} before decrementing {\tt B}, and the {\tt OUTI}, {\tt OTIR}, {\tt OUTD} and {\tt OTDR} instructions use {\tt BC} after decrementing.
\subsection{Block Instructions}
The repeated block instructions simply decrement the {\tt PC} by two so the instruction is simply re-executed. So interrupts can occur during block instructions. So, {\tt LDIR} is simply {\tt LDI} + if {\tt BC} is not {\tt 0}, decrement {\tt PC} by {\tt 2}.
\subsection{16 Bit Additions}
The 16-bit additions are a bit more complicated than the 8-bit ones. Since the Z80 is an 8-bit CPU, 16-bit additions are done in two stages: first, the lower bytes are added, then the two higher bytes. The SF, YF, HF, XF flags are affected by the second (high) 8-bit addition. ZF is set if the whole 16-bit result is 0.
\subsection{DAA Instruction}
\label{z80_undocumented_instruction_daa}
This instruction is useful when you're using BCD values. After addition or subtraction, {\tt DAA} corrects the value back to BCD again. Note that it uses the CF flag, so it cannot be used after {\tt INC} and {\tt DEC}.
Stefano Donati from Ramsoft\footnote{http://www.ramsoft.bbk.org/} has found the tables which describe the {\tt DAA} operation. The input is the A register and the CF, NF, HF flags. The result is as follows:
{
\footnotesize
\begin{tabular}{b{5.8cm}b{4.8cm}b{4.8cm}}
Depending on the NF flag, the ``diff'' from this table must be added (NF is reset) or subtracted (NF is set) to {\tt A}:
&
CF flag is affected:
&
HF flag is affected: \\
\end{tabular}
\begin{tabular}{p{5.8cm}p{4.8cm}p{4.8cm}}
% ----------------------------------
% | NF | CF | hi | HF | lo | add |
% |----|----|-----|----|-----|-----|
% | 0 | 0 | 0-9 | 0 | 0-9 | 00 |
% | 0 | 0 | 0-9 | 1 | 0-9 | 06 |
% | 0 | 0 | 0-8 | * | a-f | 06 |
% | 0 | 0 | a-f | 0 | 0-9 | 60 |
% | 0 | 1 | * | 0 | 0-9 | 60 |
% | 0 | 1 | * | 1 | 0-9 | 66 |
% | 0 | 1 | * | * | a-f | 66 |
% | 0 | 0 | 9-f | * | a-f | 66 |
% | 0 | 0 | a-f | 1 | 0-9 | 66 |
% ----------------------------------
% | 1 | 0 | 0-9 | 0 | 0-9 | 00 |
% | 1 | 0 | 0-9 | 1 | 0-9 | fa |
% | 1 | 0 | 0-8 | * | a-f | fa |
% | 1 | 0 | a-f | 0 | 0-9 | a0 |
% | 1 | 1 | * | 0 | 0-9 | a0 |
% | 1 | 1 | * | 1 | 0-9 | 9a |
% | 1 | 1 | * | * | a-f | 9a |
% | 1 | 0 | 9-f | * | a-f | 9a |
% | 1 | 0 | a-f | 1 | 0-9 | 9a |
% ----------------------------------
{\tt
\begin{tabular}[t]{c|c|c|c|c}
& high & & low & \\
CF & nibble & HF & nibble & diff \\
\hline
0 & 0-9 & 0 & 0-9 & 00 \\
0 & 0-9 & 1 & 0-9 & 06 \\
0 & 0-8 & * & A-F & 06 \\
0 & A-F & 0 & 0-9 & 60 \\
1 & * & 0 & 0-9 & 60 \\
1 & * & 1 & 0-9 & 66 \\
1 & * & * & A-F & 66 \\
0 & 9-F & * & A-F & 66 \\
0 & A-F & 1 & 0-9 & 66 \\
\hline
\end{tabular}
}
&
% ------------------------
% | CF | hi | lo | CF' |
% |----|-----|-----|-----|
% | 0 | 0-9 | 0-9 | 0 |
% | 0 | 0-8 | a-f | 0 |
% | 0 | 9-f | a-f | 1 |
% | 0 | a-f | 0-9 | 1 |
% | 1 | * | * | 1 |
% ------------------------
{\tt
\begin{tabular}[t]{c|c|c|c}
& high & low & \\
CF & nibble & nibble & CF' \\
\hline
0 & 0-9 & 0-9 & 0 \\
0 & 0-8 & A-F & 0 \\
0 & 9-F & A-F & 1 \\
0 & A-F & 0-9 & 1 \\
1 & * & * & 1 \\
\hline
\end{tabular}
}
&
% -----------------------
% | NF | HF | lo | HF' |
% |----|----|-----|-----|
% | 0 | * | 0-9 | 0 |
% | 0 | * | a-f | 1 |
% -----------------------
% | 1 | 0 | * | 0 |
% | 1 | 1 | 6-f | 0 |
% | 1 | 1 | 0-5 | 1 |
% -----------------------
{\tt
\begin{tabular}[t]{c|c|c|c}
& & low & \\
NF & HF & nibble & HF' \\
\hline
0 & * & 0-9 & 0 \\
0 & * & A-F & 1 \\
1 & 0 & * & 0 \\
1 & 1 & 6-F & 0 \\
1 & 1 & 0-5 & 1 \\
\hline
\end{tabular}
}
\\
\end{tabular}
}
SF, YF, XF are copies of bit 7, 5, 3 of the result respectively; ZF is set according to the result and NF is always unchanged.
\section{Interrupts}
\label{z80_interrupts}
There are two types of interrupts, maskable and non-maskable. The maskable type is ignored if {\tt IFF1} is reset. Non-maskable interrupts (NMI) will are always accepted, and they have a higher priority, so if both are requested at the same time, the NMI will be accepted first.
For the interrupts, the following things are important: interrupt Mode (set with the {\tt IM 0, IM 1, IM 2} instructions), the interrupt flip-flops ({\tt IFF1} and {\tt IFF2}), and the {\tt I} register. When a maskable interrupt is accepted, the external device can put a value on the data bus.
Both types of interrupts increase the {\tt R} register by one when accepted.
\subsection{Non-Maskable Interrupts (NMI)}
When an NMI is accepted, {\tt IFF1} is reset. At the end of the routine, {\tt IFF1} must be restored (so the running program is not affected). That's why {\tt IFF2} is there; to keep a copy of {\tt IFF1}.
An NMI is accepted when the \NoLinkChipPinLabel{NMI} pin on the Z80 is made low (edge-triggered). The Z80 responds to the change of the line from +5 to 0 - so the interrupt line doesn't have a state, it's just a pulse. When this happens, a call is done to address \MemAddr{0066} and {\tt IFF1} is reset so the routine isn't bothered by maskable interrupts. The routine should end with an {\tt RETN} (RETurn from Nmi) which is just a usual {\tt RET} but also copies {\tt IFF2} to {\tt IFF1}, so the IFFs are the same as before the interrupt.
You can check whether interrupts were disabled or not during an NMI by using the {\tt LD A,I} or {\tt LD A,R} instruction. These instructions copy {\tt IFF2} to the PV flag.
Accepting an NMI costs 11 t-states.
\subsection{Maskable Interrupts (INT)}
If the \NoLinkChipPinLabel{INT} line is low and {\tt IFF1} is set, a maskable interrupt is accepted - whether or not the last interrupt routine has finished. That's why you should not enable interrupts during such a routine, and make sure that the device that generated it has put the \NoLinkChipPinLabel{INT} line up again before ending the routine. So unlike NMI interrupts, the interrupt line has a state; it's not a pulse.
When an interrupt is accepted, both {\tt IFF1} and {\tt IFF2} are cleared, preventing another interrupt from occurring which would end up as an infinite loop (and overflowing the stack). What happens next depends on the Interrupt Mode.
A device can place a value on the data bus when the interrupt is accepted. Some computer systems do not utilize this feature, and this value ends up being {\tt \$FF}.
\begin{description}
\item[Interrupt Mode 0]
This is the 8080 compatibility mode. The instruction on the bus is executed (usually an {\tt RST} instruction, but it can be anything). {\tt I} register is not used. Assuming it's a {\tt RST} instruction, accepting this takes 13 t-states.
\item[Interrupt Mode 1]
This is the 8080 compatibility mode. The instruction on the bus is executed (usually an {\tt RST} instruction, but it can be anything). {\tt I} register is not used. Assuming it's a {\tt RST} instruction, accepting this takes 13 t-states.
\item[Interrupt Mode 2]
A call is made to the address read from memory. What address is read from is calculated as follows: $(I\ register) \times 256 + (value\ on\ bus)$. Zilog's user manual states (very convincingly) that the least significant bit of the address is always 0, so they calculate the address that is read from as: $(I\ register) \times 256 + (value\ on\ bus \wedge \mathtt{\$FE})$. I have tested this and it's not correct. Of course, a word (two bytes) is read, making the address where the call is made to. In this way, you can have a vector table for interrupts. Accepting this interrupt type costs 19 t-states.
\end{description}
At the end of a maskable interrupt, the interrupts should be enabled again. You can assume that was the state of the IFFs because otherwise the interrupt wasn't accepted. So, an interrupt routine always ends with an {\tt EI} and a {\tt RET} ({\tt RETI} according to the official documentation, more about that later):
\begin{tcblisting}{}
InterruptRoutine:
...
EI
RETI or RET
\end{tcblisting}
Note a fact about {\tt EI}: a maskable interrupt isn't accepted directly after it, so the next opportunity for an interrupt is after the {\tt RETI}. This is very useful; if the \NoLinkChipPinLabel{INT} line is still low, an interrupt is accepted again. If this happens a lot and the interrupt is generated before the {\tt RETI}, the stack could overflow (since the routine would be called again and again). But this property of {\tt EI} prevents this.
{\tt DI} is not necessary at the start of the interrupt routine: the interrupt flip-flops are cleared when accepting the interrupt.
You can use {\tt RET} instead of {\tt RETI}, depending on the hardware setup. {\tt RETI} is only useful if you have something like a Z80 PIO to support daisy-chaining: queuing interrupts. The PIO can detect that the routine has ended by the opcode of {\tt RETI}, and let another device generate an interrupt. That is why I called all the undocumented {\tt EDxx} {\tt RET} instructions {\tt RETN}: All of them operate alike, the only difference of {\tt RETI} is its specific opcode which the Z80 PIO recognises.
\subsection{Things Affecting the Interrupt Flip-Flops}
\label{z80_interrupts_flipflop}
All the IFF related things are:
\begin{tabular}{llll}
Accept NMI & {\tt IFF1} & {\tt IFF2} \\
CPU reset & {\tt 0} & {\tt 0}\\
{\tt DI} & {\tt 0} & {\tt 0}\\
{\tt EI} & {\tt 1} & {\tt 1}\\
Accept INT & {\tt 0} & {\tt 0}\\
Accept NMI & {\tt 0} & -\\
{\tt RETI/N}& {\tt IFF2} & - & All the {\tt EDxx} {\tt RETI/N} instructions\\
{\tt LD A,I / LD A,R} & - & - & Copies {\tt IFF2} into {\tt PV} flag
\end{tabular}
If you're working with a Z80 system without NMIs (like the MSX), you can forget all about the two separate IFFs; since an NMI isn't ever generated, the two will always be the same.
Some documentation says that when an NMI is accepted, {\tt IFF1} is first copied into {\tt IFF2} before {\tt IFF1} is cleared. If this is true, the state of {\tt IFF2} is lost after a nested NMI, which is undesirable. Have tested this in the following way: make sure the Z80 is in {\tt EI} mode, generate an NMI. In the NMI routine, wait for another NMI before executing {\tt RETN}. In the second NMI {\tt IFF2} was still set, so {\tt IFF1} is {\em not} copied to {\tt IFF2} when accepting an NMI.
Another interesting fact: I was trying to figure out whether the undocumented {\tt ED} {\tt RET} instructions were {\tt RETN} or {\tt RETI}. I tested this by putting the machine in {\tt EI} mode, wait for an NMI and end with one of the {\tt ED} {\tt RET} instructions. Then execute a {\tt HALT} instruction. If {\tt IFF1} was not restored, the machine would hang but this did not happen with any of the instructions, including the documented {\tt RETI}!
Since every interrupt routine must end with {\tt EI} followed by {\tt RETI} officially, It does not matter that {\tt RETI} copies {\tt IFF2} into IFF1; both are set anyway.
\subsection{HALT Instruction}
The HALT instruction halts the Z80; it does not increase the PC so that the instruction is re-executed until a maskable or non-maskable interrupt is accepted. Only then does the Z80 increase the PC again and continues with the next instruction. During the HALT state, the HALT line is set. The PC is increased before the interrupt routine is called.
\subsection{Where interrupts are accepted}
During the execution of instructions, interrupts won't be accepted. Only {\em between} instructions. This is also true for prefixed instructions.
Directly after an {\tt EI} or {\tt DI} instruction, interrupts aren't accepted. They're accepted again after the instruction after the {\tt EI} ({\tt RET} in the following example). So for example, look at this MSX2 routine that reads a scanline from the keyboard:
\begin{tcblisting}{}
LD C, A
DI
IN A, (&AA)
AND &F0
ADD A, C
OUT (&AA), A
EI
IN A, (&A9)
RET
\end{tcblisting}
You can assume that there never is an interrupt after the {\tt EI}, before the {\tt IN A,(\$A9)} - which would be a problem because the MSX interrupt routine reads the keyboard too.
Using this feature of {\tt EI}, it is possible to check whether it is true that interrupts are never accepted during instructions:
\begin{tcblisting}{}
DI
|make sure interrupt is active|
EI
|insert instruction to test|
InterruptRoutine:
|store PC where interrupt was accepted|
RET
\end{tcblisting}
And yes, for all instructions, including the prefixed ones, interrupts are never accepted during an instruction. Only after the tested instruction. Remember that block instructions simply re-execute themselves (by decreasing the PC with 2) so an interrupt is accepted after each iteration.
Another predictable test: at the ``insert instruction to test'' insert a large sequence of {\tt EI} instructions. Of course, during the execution of the {\tt EI} instructions, no interrupts are accepted.
\pagebreak % we want to keep this paragraph together on the next page
But now for the interesting stuff. {\tt ED} or {\tt CB} make up instructions, so interrupts are accepted after them. But {\tt DD} and {\tt FD} are prefixes, which only slightly affects the next opcode. If you test a large sequence of {\tt DD}s or {\tt FD}s, the same happens as with the {\tt EI} instruction: no interrupts are accepted during the execution of these sequences.
This makes sense if you think of {\tt DD} and {\tt FD} as a prefix that sets the ``use {\tt IX} instead of {\tt HL}'' or ``use {\tt IY} instead of {\tt HL}'' flag. If an interrupt was accepted after {\tt DD} or {\tt FD}, this flag information would be lost, and:
{\tt
{\qquad}DD 21 00 00{\qquad}LD IX, 0
}
could be interpreted as a simple {\tt LD HL,0} if the interrupt was after the last {\tt DD}. Which never happens, so the implementation is correct. Although I haven't tested this, as I imagine the same holds for NMI interrupts.
Also see section \XRef{zx_next_interrupts} for details on handling interrupts on ZX Spectrum Next.
\section{Timing and R register}
\subsection{R register and memory refresh}
During every first machine cycle (beginning of instruction or part of it - prefixes have their own M1 two), the memory refresh cycle is issued. The whole IR register is put on the address bus, and the \NoLinkChipPinLabel{RFSH} pin is lowered. It's unclear whether the Z80 increases the {\tt R} register before or after putting IR on the bus.
The {\tt R} register is increased at every first machine cycle (M1). Bit 7 of the register is never changed by this; only the lower 7 bits are included in the addition. So bit 7 stays the same, but it can be changed using the
{\tt LD R,A} instruction.
Instructions without a prefix increase {\tt R} by one. Instructions with an {\tt ED}, {\tt CB}, {\tt DD}, {\tt FD} prefix, increase {\tt R} by two, and so do the {\tt DDCBxxxx} and {\tt FDCBxxxx} instructions (weird enough). Just a stray {\tt DD} or {\tt FD} increases the {\tt R} by one. {\tt LD A,R} and {\tt LD R,A} access the {\tt R} register after it is increased by the instruction itself.
Remember that block instructions simply decrement the {\tt PC} with two, so the instructions are re-executed. So {\tt LDIR} increases {\tt R} by {\tt BC} $\times$ 2 (note that in the case of {\tt BC} = 0, {\tt R} is increased by \MemAddr{10000} $\times$ 2, effectively 0).
Accepting a maskable or non-maskable interrupt increases the {\tt R} by one.
After a hardware reset, or after power on, the {\tt R} register is reset to 0.
That should cover all there is to say about the {\tt R} register. It is often used in programs for a random value, which is good but of course not truly random.
\pagebreak
\section{Errors in Official Documentation}
Some official Zilog documentation contains errors. Not every documentation has all of these mistakes, so your milage may vary, but these are just things to look out for.
\begin{itemize}
\item
The flag affection summary table shows that {\tt LDI}/{\tt LDIR}/{\tt LDD}/{\tt LDDR} instructions leave the SF and ZF in an undefined state. This is not correct; the SF and ZF flags are unaffected.
\item
Similarly, the same table shows that {\tt CPI}/{\tt CPIR}/{\tt CPD}/{\tt CPDR} leave the SF and HF flags in an undefined state. Not true, they are affected as defined elsewhere in the documentation.
\item
Also, the table says about {\tt INI}/{\tt OUTD}/etc ``Z=0 if B $<>$ 0 otherwise Z=0''; of course the latter should be Z=1.