| 
											
											Z80 Special Reset
											 Although not mentioned in Zilog 
											databooks the Z80 CPU supports two 
											types of reset cycle, normal and 
											special. A normal reset disables the 
											maskable interrupt, selects 
											interrupt mode 0, zeroes registers I 
											& R and zeroes the program counter 
											(PC). A special reset only does the 
											last of these. Zilog literature also 
											states that
											
											RESET must be active for at 
											least three clock cycles (3T) before 
											being properly accepted. Tests with 
											short reset pulses 1T or 2T long 
											have shown that this is not true and 
											the reason for Zilog saying 
											otherwise is explained later.  What is the special reset?
											 
											
											US Patent 4486827 describes the 
											Z80 special reset and the abstract 
											is succinct:  "A special reset function is 
											provided in the CPU, using the same 
											control input to the CPU as a normal 
											reset, to reset only the program 
											counter to facilitate the use of a 
											single CPU in a microprocessor 
											development system."  The patent document should be 
											downloaded to learn more about the 
											intended application of the special 
											reset. It enables breakpoints whilst 
											debugging Z80 code that preserve the 
											complete state of the system, except 
											for PC which is easily saved. 
											Nothing is put on the stack unlike 
											when taking a "snapshot" using the 
											non-maskable interrupt (possibly 
											destroying data) and in any case the
											
											NMI pin might not be 
											available. Sharing the same 64K 
											address space does mean that during 
											development the user cannot access 
											the very top of memory where the 
											monitoring software is located but 
											changes to assembly code to cater 
											for this are normally trivial.  I used such a development 
											system, a Zilog in-circuit emulator 
											(ICE), whilst working for Memotech 
											at Oxford and Witney thirty years 
											ago but was unaware of the special 
											reset and the crucial part it played 
											in the ICE until a few weeks ago.
											 How the special reset is 
											generated  
											
  Very precise timing is required 
											to generate a special reset signal. 
											The figure above shows a Z80 
											instruction opcode fetch (M1 cycle). 
											To be special
											
											RESET must be low only at the 
											rising edge of clock state M1T2 as 
											shown in red (the low pulse width is 
											illustrative). A reset will be 
											normal if
											
											RESET is low at any rising 
											edge of CLK other than M1T2. The 
											results of tests with reset pulses 
											1T and 2T long during M1 cycles are 
											shown below. (Other M cycles were 
											not considered as a special reset 
											during these is impossible.)  
											
											
											RESET low at rising edge 
											of   Type ofM1T1 M1T2 M1T3 M1T4 ....      reset
 
											   X                           NormalX                     Special
 X                 Normal
 X            Normal
 
											   X    X                      NormalX    X                 Normal
 X    X            Normal
 X    X       Normal
 
											
											Note that a reset pulse that is very 
											short (much less than 1T long) will 
											still generate a reset provided the 
											minimum
											
											RESET to rising edge of CLK 
											setup and hold times are met. For 
											the Z80A these are 60 ns and 0 ns 
											respectively for the NMOS version or 
											60 ns and 10 ns respectively for the 
											CMOS version. (The 10 ns hold time 
											for CMOS also applies to
											
											WAIT,
											
											BUSREQ and
											
											INT.)  How the CPU detects the 
											special reset  Below is a modified version of 
											Fig. 11 from the patent with changes 
											made for clarity and consistency. 
											The external logic with two D-type 
											flip-flops is just one way to create 
											the special reset pulse (note that 
											M1 here is
											
											M1 inverted). In the tests 
											performed the
											
											RESET signal was a registered 
											output from a programmable logic 
											device (PLD) clocked on the falling 
											edge of CLK, enabled when
											
											M1 is low and
											
											MREQ is high for the special 
											reset.  
  As there is only one reset pin 
											the Z80 designers needed to include 
											extra circuitry to distinguish 
											between the two reset functions. 
											Inside the chip are the equivalent 
											of three D-type flip-flops, two with 
											enable and one with enable and 
											clear. The RESI f-f samples the
											
											RESET input on every rising 
											edge of CLK, the normal reset f-f 
											samples RESI on every falling edge 
											of CLK except in M1T2 and the 
											special reset f-f samples RESI on 
											the falling edge in M1T2 only.  
											
											NRES acts as an asynchronous 
											clear for the special reset f-f. 
											After
											
											RESET goes low during M1T1 
											RESI goes high on the rising edge of 
											M1T2 and CLRPC goes high on the 
											falling edge. If
											
											RESET is still low at the 
											next rising edge (at the start of 
											M1T3)
											
											NRES will go low on the 
											falling edge and clear CLRPC. 
											Similarly if
											
											RESET is low at the rising 
											edges of both M1T1 and M1T2
											
											NRES will prevent CLRPC going 
											high.  Therefore a 2T reset pulse is 
											sufficient to produce a normal reset 
											provided the minimum setup and hold 
											times are met and the tests shown 
											earlier prove this to be the case. 
											However an asynchronous reset signal 
											cannot be relied upon to always meet 
											the setup time and it might not be 
											detected until almost a whole clock 
											cycle after becoming active which is 
											why databooks say
											
											RESET should be low for at 
											least 3T.  After the special reset is 
											detected  CLRPC going high is no guarantee 
											that the reset will be special but 
											if not cleared by
											
											NRES CLRPC will stay high 
											until the falling edge of T2 in the 
											next M1 cycle. The patent shows 
											CLRPC sampled on the rising edge of 
											M1T2 at which time the type of reset 
											is not in doubt and PC will be 
											zeroed if CLRPC is set. However an 
											opcode fetch from address zero must 
											wait until the following M1 cycle as 
											the incremented PC has already been 
											placed on the address bus and
											
											M1 has gone low. Thus 
											following the instruction when
											
											RESET is active there is an 
											M1 cycle in which the opcode of the 
											next instruction is fetched and the 
											main if not only job of the CPU 
											during this cycle is to zero PC.  The patent describes external 
											circuitry with a multiplexer that 
											zeroes the data bus to ensure the 
											opcode is read as a NOP (although 
											test results indicate the opcode is 
											ignored anyway) and a 16-bit 
											register that holds the last value 
											of PC before it changes to zero. 
											This is the address to which the CPU 
											should jump after the special reset 
											routines have finished and so the 
											instruction here must not be 
											executed before then. Of course if 
											the special reset was generated at a 
											pre-determined breakpoint this 
											continuation address would be known 
											beforehand.  To summarize the instruction in 
											which the special reset pulse occurs 
											is completed, then the opcode of the 
											following instruction is fetched but 
											appears to be treated as a NOP in a 
											similar way to the halt state, then 
											the opcode at address zero is 
											fetched. No return address is pushed 
											automatically onto the stack as the 
											special reset is not an interrupt 
											and if PC is not saved during the 
											reset or the breakpoint specified in 
											advance the CPU will not know the 
											correct address to resume normal 
											program execution.  Prefixed instructions and the 
											special reset  Tests have shown that the special 
											reset is accepted in the first or 
											second M1 cycle of an instruction 
											prefixed by CB, the only difference 
											being that the reset takes effect 4T 
											sooner when
											
											RESET is low during the 
											second. Identical behaviour is 
											assumed for the other prefixes DD, 
											ED and FD. Thus the next M1 cycle 
											after an accepted special reset 
											pulse might not always be an opcode 
											fetch of a new instruction. Prefixed 
											instructions are followed by a 
											disregarded opcode fetch in the same 
											way as non-prefixed ones and two 
											examples of program execution are 
											shown below.  
											
											PC    Instruction  Comments  0012  RLC B        Special reset 
											during fetch from 00120014  PUSH BC      Fetch from 0014, 
											opcode ignored, 0000 -> PC
 0000  xxx          Fetch from 0000, 
											starts 12T after start of fetch from 
											0012
 0012  RLC B        Special reset 
											during fetch from 00130014  PUSH BC      Fetch from 0014, 
											opcode ignored, 0000 -> PC
 0000  xxx          Fetch from 0000, 
											starts 8T after start of fetch from 
											0013
       xxx = don't careAll addresses and numbers in 
											instructions are in hexadecimal
 
											
											Halt and the special reset
											 An interesting situation arises 
											when there is a special reset pulse 
											after a HALT instruction. The halt 
											state can be exited by a maskable 
											interrupt (if enabled), a 
											non-maskable interrupt or either 
											type of reset. Until one of these 
											happens databooks say that "the CPU 
											executes NOPs to maintain memory 
											refresh" without giving any more 
											detail. HALT needs to be executed 
											only once to place the CPU in the 
											halt state and if the HALT opcode is 
											continually read thereafter this 
											would have the same effect 
											presumably as executing NOPs. If 
											HALT were replaced by NOP after
											
											HALT has gone low would this 
											be another way to exit the halt 
											state?  The answer is no. When
											
											HALT is low PC has already 
											been incremented and the opcode 
											fetched is for the instruction after 
											HALT. The halt state stops this 
											instruction from being executed and 
											PC from incrementing so this opcode 
											is read again and again until an 
											exit condition occurs. When an 
											interrupt occurs during the halt 
											state PC is pushed unchanged onto 
											the stack as it is already the 
											correct return address. This is no 
											different from an interrupt when not 
											halted as
											
											INT and
											
											NMI are sampled and accepted 
											at the end of an instruction by 
											which time PC has incremented. (N.B. 
											What "The Undocumented Z80 
											Documented" says about HALT and PC 
											is wrong.)  If a special reset pulse occurs 
											when
											
											HALT is low the halt state is 
											exited immediately and the opcode of 
											the instruction after HALT will be 
											fetched and executed with no delay. 
											This is possible because special 
											reset is sampled on the rising edge 
											of M1T2 and the opcode is sampled on 
											the rising edge of M1T3. (Tests show 
											that
											
											HALT goes high after the 
											falling edge of M1T2.) Once the 
											instruction after HALT is completed 
											there is an opcode fetch of the next 
											instruction then a fetch from 
											address zero as already described.
											 Apart from what is preserved it 
											can be seen that there is another 
											difference between a normal and a 
											special reset during the halt state: 
											the latter executes an instruction 
											between the HALT and the actual 
											reset. This could be used to save PC 
											without the need for an external 
											register. CALL pushes a return 
											address but the two memory reads to 
											get the address of the subroutine 
											are a waste of time as it is never 
											actually called. RST is a better 
											choice as it is single-byte and 
											faster. RST 18 was used during tests 
											but any of the eight would do as the 
											restart address is effectively 
											redundant and RST 0 is perhaps the 
											most appropriate.  Tests indicate that there is a 
											significant difference between 
											special resets when unhalted and 
											halted. For the latter the halt 
											state appears to prevent PC from 
											incrementing at the end of the 
											instruction after HALT, even though
											
											HALT goes high before the 
											rising edge of M1T3 during the 
											opcode fetch. PC holds the address 
											of the last byte of the instruction 
											after it finishes executing and RST 
											pushes its own address onto the 
											stack. When unhalted both addresses 
											will be one more. Three examples 
											from testing are shown below, with M 
											cycle lengths.  
											
											0011  xxx          Not HALT0012  HALT
 0013  RST 18       Special reset 
											during fetch from 0013, M1 = 5T, M2 
											= 3T, M3 = 3T * **
 0018  xxx          Fetch from 0018, 
											opcode ignored, 0000 -> PC, M1 = 4T
 0000  xxx          Fetch from 0000, 
											starts 15T after start of fetch from 
											0013
 0011  xxx          Not HALT0012  HALT
 0013  PUSH AF      Special reset 
											during fetch from 0013, M1 = 5T, M2 
											= 3T, M3 = 3T **
 0013  PUSH AF      Fetch from 0013 
											again, opcode ignored, 0000 -> PC, 
											M1 = 4T
 0000  xxx          Fetch from 0000, 
											starts 15T after start of first 
											fetch from 0013
 0011  xxx          Not HALT0012  HALT
 0013  LD (8000),A  Special reset 
											during fetch from 0013, M1 = 4T, M2 
											= 3T, M3 = 3T, M4 = 3T **
 0015  DB 80        Fetch from 0015, 
											opcode ignored, 0000 -> PC, M1 = 4T 
											***
 0000  xxx          Fetch from 0000, 
											starts 17T after start of fetch from 
											0013
   * Address pushed onto stack = 
											0013** HALT 
											low at rising and falling edges of 
											M1T1 and M1T2
 *** High byte of address read as 
											opcode but ignored
 
											
											The state of
											
											HALT at the rising edge of 
											CLK when
											
											RESET is low could be stored 
											so that the special reset routines 
											know whether or not PC should be 
											incremented before resuming normal 
											program execution. An alternative 
											solution that would work when halted 
											or unhalted would be to store the 
											value of PC when
											
											RESET is low and replace all 
											opcodes with NOP until there is a 
											fetch from address zero. However 
											memory cycles would have to be 
											continually examined to ensure the 
											special reset pulse does not occur 
											immediately after a prefix fetch.
											 If the special reset pulse occurs 
											when
											
											HALT is high during a HALT 
											opcode fetch then PC is incremented 
											at the end of the fetch and
											
											HALT goes low very briefly. 
											If the special reset pulse occurs 
											when
											
											HALT is low during a HALT 
											fetch (two consecutive HALTs) then
											
											HALT goes high before the 
											rising edge of M1T3, PC is not 
											incremented at the end of the fetch 
											and HALT goes low again very 
											briefly. Examples of program 
											execution in both cases are shown 
											below.  
											
											0011  xxx          Not HALT0012  HALT         Special reset 
											during fetch from 0012
 0013  xxx          Fetch from 0013, 
											opcode ignored, 0000 -> PC *
 0000  xxx          Fetch from 0000, 
											starts 8T after start of fetch from 
											0012
 0011  xxx          Not HALT0012  HALT
 0013  HALT         Special reset 
											during first fetch from 0013 **
 0013  HALT         Fetch from 0013 
											again, opcode ignored, 0000 -> PC *
 0000  xxx          Fetch from 0000, 
											starts 8T after start of first fetch 
											from 0013
  * HALT 
											low at rising edge of M1T1 only** HALT 
											low at rising and falling edges of 
											M1T1 and M1T2
 
											
											How the tests were done  Dave Stevenson's
											
											MTX Plus+ CPU board was used for 
											testing the special reset. Some 
											modifications were needed first, in 
											particular creating a separate reset 
											signal for the Z80 only. The onboard 
											Altera MAX 7000 series CPLD 
											contained all the necessary test 
											logic and 64 bytes of Z80 machine 
											code so that only one device needed 
											to be programmed. The initial test 
											program is shown below.  
											
											0000  JR NC,0002   interrupt vector 
											table DW 00300002  LD A,I       or LD A,R
 0004  NOP
 0005  RLCA
 0006  JR C,0028    jump if bit 7 of 
											I or R set
 0008  LD A,80      opcodes at 
											0008-000F zeroed after 2nd fetch 
											from 0000
 000A  LD I,A       or LD R,A
 000C  NOP
 000D  EI
 000E  IM 2         or IM 1
 0010  NOP          special reset 
											generated at 001x (varied) after 1st 
											fetch from 0000
 0020  HALT         here if normal 
											reset, generate interrupt, stop,
											
											INT low
 0028  HALT         here if special 
											reset, generate interrupt
 0030  HALT         here if IM 2 
											interrupt accepted, stop,
											
											INT high
 0038  HALT         here if IM 1 
											interrupt accepted, stop,
											
											INT high
 
											
											There is a NOP at any address not 
											listed up to 003F. The first two 
											bytes of the program form the 
											complete interrupt mode 2 vector 
											table as zero is placed on the data 
											bus during a maskable interrupt 
											acknowledge cycle. 30 was chosen so 
											that IM 1 and IM 2 tests end at 
											different addresses and 30 00 is a 
											harmless instruction as whatever the 
											state of the carry flag the second 
											instruction after a reset will be 
											read from address 0002. Note that 
											only A5-A0 were used for address 
											decoding, the I register can have 
											any value during IM 2 tests and any 
											combination of I or R and IM 1 or IM 
											2 is permissible.  Each test began with a button 
											press generating a 200 ms normal 
											reset. Code at 0000-000F was then 
											executed, followed by a short reset 
											pulse (normal or special) shortly 
											after address 0010. A special reset 
											preserved I and R and the CPU 
											executed the HALT at 0028. A normal 
											reset zeroed I and R and the CPU 
											executed the HALT at 0020 (opcodes 
											from 0008-000F were zeroed after 
											this second reset). A maskable 
											interrupt was generated when the 
											address reached 002x, accepted only 
											if the reset was special. Thus the 
											state of
											
											INT at the end of the test 
											was a simple indication of the type 
											of reset.  Opcodes were placed carefully to 
											minimise the amount of logic 
											required even though there was ample 
											available. The CPLD has 128 
											macrocells with five combinatorial 
											product terms per cell. (Unused 
											terms can be borrowed from adjacent 
											cells if required.) As it turned out 
											only eight macrocells were needed to 
											create 17 non-zero bytes with three 
											to five product terms per data bit 
											and 33 in total for D7-D0. Later 
											tests utilised more logic as 
											instructions were added in the range 
											0010-001F and the results of these 
											were listed earlier.  In order to see more information 
											Dave Stevenson's
											
											diagnostic card was connected. 
											This has 7-segment LEDs that can 
											latch and display the contents of 
											the address and data buses. The CPLD 
											output a signal that latched the 
											final PC and various data values 
											during opcode fetches when halted at 
											the end of each test. The data bus 
											is ignored by the CPU when in the 
											halt state and therefore can be used 
											by other devices. Initially one data 
											value was displayed, then two and 
											ultimately four. A counter was 
											implemented with the refresh address 
											as the low bits to display each data 
											byte in turn for about one second.
											 The values displayed on the data 
											LEDs included the last PC after the 
											special reset before the fetch from 
											address zero, the number of fetches 
											from address zero (a reset count), 
											the number of halt cycles completed, 
											the number of T-states from the 
											reset pulse to the fetch from 
											address zero and the last 16 
											successive samples at the falling 
											edge of CLK before the fetch from 
											address zero of
											
											HALT and
											
											MREQ. The latter showed 
											clearly the different types of M 
											cycle. (It was necessary to also 
											sample
											
											HALT on the rising edge of 
											CLK to detect the very short pulses 
											discussed earlier.)  As the tests were not about speed 
											a 1 MHz CLK signal was output by the 
											CPLD. Any signals sampled by the CPU 
											on the rising edge of CLK were 
											clocked using the falling edge in 
											the CPLD and any signal from the CPU 
											clocked on the falling edge was 
											sampled by the CPLD on the rising 
											edge. The state of
											
											MREQ,
											
											M1 and
											
											RFSH at the falling edge of 
											CLK was used to distinguish each of 
											the four T states during M1 cycles 
											as shown below. (Using the rising 
											edge of CLK gives ambiguous 
											results.)  
											
											At falling edge of CLK   T stateMREQ  M1  RFSH
     H    L    H            M1T1L    L    H            M1T2
 H    H    L            M1T3
 L    H    L            M1T4
 
											
											Tests used a variety of different 
											CPUs from Zilog, Mostek and SGS in 
											NMOS and CMOS versions. A genuine 
											Zilog CPU was used mainly and other 
											brands only as a check. The special 
											reset behaviour was the same no 
											matter which CPU was tested. The 
											only difference detected was that 
											register B does not have the same 
											value on power-up in the CMOS 
											version compared to NMOS.  Conclusions  The Z80 special reset has been 
											tested and works as described in the 
											patent. A difference was detected in 
											the program counter just before the 
											special reset takes effect depending 
											on whether the CPU was halted or 
											unhalted. Normal reset pulses less 
											than 3T long were also tested 
											successfully.  Thanks  A very special thank you to Dave 
											Stevenson for not only hosting this 
											webpage and allowing his MTX Plus+ 
											project to be derailed (or at least 
											shunted onto a slow branch line) but 
											also performing all the tests and 
											reporting the results, often without 
											being told what they were all about. 
											The whole process took far longer 
											than anticipated and throughout Dave 
											was remarkably patient and 
											good-humoured.  I have given the information 
											above in good faith and as 
											accurately as I can. Further study 
											might show that it contains errors 
											but I leave that to others!  Tony BrewerDecember 2014
 |