Z80 Protocol Decoder

for bbc micro/electron hardware, peripherals & programming issues (NOT emulators!)
User avatar
hoglet
Posts: 7487
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Z80 Protocol Decoder

Post by hoglet » Wed Aug 08, 2018 8:34 pm

Coeus wrote:
Wed Aug 08, 2018 7:58 pm
Does it make any difference which interrupt mode is in use?
It's hard to tell at the moment, as I have no way of easily running my own code yet on the Spectrum +2. It's not a system I'm particularly familiar with, and I'm currently reliant on exiting programs I can load in from tape. Very primitive compared to what I'm used to!

I think this needs to be systematically investigated. First, you would need to setup a test case where a LDIR is consistently interrupted. Then it should be possible, by changing just one thing at a time, to determine what has an influence over the results.

Dave

gdevic
Posts: 4
Joined: Mon Aug 06, 2018 1:13 pm
Contact:

Re: Z80 Protocol Decoder

Post by gdevic » Wed Aug 08, 2018 8:42 pm

As far as I know, nobody has done this kind of investigation yet. It would also be interesting to see what happens with CPIR/CPDR when interrupted, as well. The known "formula" for it's YF/XF is complex but it gave quite a good insight into the internal operation on that data path segment.

dp11
Posts: 829
Joined: Sun Aug 12, 2012 8:47 pm
Contact:

Re: Z80 Protocol Decoder

Post by dp11 » Wed Aug 08, 2018 8:46 pm

sound a bit like you need a protocol encoder to drive signals on to the bus , fire interrupts and clock the cpu. No need for rom or ram

User avatar
jgharston
Posts: 3209
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield
Contact:

Re: Z80 Protocol Decoder

Post by jgharston » Thu Aug 09, 2018 2:37 pm

Could be a red herring, but it could well be something floating on the bus when the interupt happens. The repeating instructions are "odd" in that they decrement the PC to do the repeat, that PC decrement could be related.

Another thought, flags bit 5 and bit 3 are usually set to bit 5 and 3 of some data that is being processed, documentation says bit 5 is set from bit one of some internal data. Have you checked if it is actually bit five?

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

TonyB
Posts: 60
Joined: Sat Aug 11, 2018 6:45 pm
Contact:

Re: Z80 Protocol Decoder

Post by TonyB » Sat Aug 11, 2018 7:54 pm

gdevic wrote:
Mon Aug 06, 2018 3:13 pm
What a great thread!

The "special reset" is described in the "US4486827" patent: https://drive.google.com/file/d/0BykuPm ... mMwcVlOWWM
It is used for breakpoints and is the reason a real reset cycle needs to be several clocks long.
The reset pulse can be very short, much less than 1T. I studied the Z80 Special Reset in detail a few years ago: http://www.primrosebank.net/computers/z ... _reset.htm. Please note what the first paragraph says about which registers are initialised on reset.

"The Undocumented Z80 Documented" has also been mentioned in this thread but it has not been updated for years and is not 100% correct, e.g. most of what it says about HALT is wrong, as explained on the Special Reset page.

There was a topic in one of the World of Spectrum forums by someone who investigated the Z80 registers after a reset. By an amazing piece of detective work he discovered the Special Reset without knowing about it. I'll try to find the topic again if it's still available as it's well worth reading, even if you consider the Special Reset to have little or no practical application. (In fact it was included in the Z80 to make the hardware in the Zilog in-circuit emulator simpler.)
Last edited by TonyB on Sat Aug 11, 2018 8:12 pm, edited 1 time in total.

TonyB
Posts: 60
Joined: Sat Aug 11, 2018 6:45 pm
Contact:

Re: Z80 Protocol Decoder

Post by TonyB » Sat Aug 11, 2018 8:58 pm

I've found the topic mentioned above. Here's the link to where it becomes interesting:
https://www.worldofspectrum.org/forums/ ... ent_539714

The page might take a long time to load as WoS can be slow.
Could it be that after RESET is asserted and the HALT condition is exited, the CPU has time to fetch, decode and execute one more instruction before PC is set to 0000?
Yes!

TonyB
Posts: 60
Joined: Sat Aug 11, 2018 6:45 pm
Contact:

Re: Z80 Protocol Decoder

Post by TonyB » Sun Aug 12, 2018 5:36 pm

hoglet wrote:
Mon Aug 06, 2018 2:55 pm
After fixing a few bugs, I'm now able to decode this trace without any failures being flagged by my Z80 emulation code.

So I'm pretty happy now that the emulation is in good shape.

There are just two cases I know of now where I'm not able to predict the correct values for the undocumented F5/F3 flags (a.k.a. YF and XF):
- following SCF (Set carry) or CCF (Complement carry)
- following LDIR (and probably LDDR/LDI/LDD)

The first case (with SCF/CCF) I understand. It turns out the setting of the undocumented F5/F3 flags in SCF and CCF actually depends on whether the preceding instruction modified the flags or not. This is described in this post. I don't see any problem in implementing this, I just haven't done so yet,

The second case (with LDIR) has me very confused. It seems that the current understanding is that F5 and F3 flags take on bits 1 and 3 of (data + A). I'm doing this, and still seeing errors.

Code: Select all

 FETCH 0 0 1 0 1 1 1 0 ed * 
 FETCH 0 0 1 0 1 1 1 0 b0 * 
 MEMRD 1 0 1 0 1 1 1 0 38 * : Rd=38
 MEMWR 1 1 0 0 1 1 1 0 38 * : Wd=38
0E82 : ED B0           : LDIR                 : 21/ 0 : A=38 F= Z0 0V   BC=00B0 DE=5A50 HL=5A4F IX=F7FF IY=5C3A SP=FF50

 FETCH 0 0 1 0 1 1 1 0 ed * 
 FETCH 0 0 1 0 1 1 1 0 b0 * 
 MEMRD 1 0 1 0 1 1 1 0 38 * : Rd=38
 MEMWR 1 1 0 0 1 1 1 0 38 * : Wd=38
0E82 : ED B0           : LDIR                 : 23/ 0 : A=38 F= Z0 0V   BC=00AF DE=5A51 HL=5A50 IX=F7FF IY=5C3A SP=FF50

INTACK 0 1 1 1 0 1 1 0 ff * 
 MEMWR 1 1 0 0 1 1 1 0 0e * 
 MEMWR 1 1 0 0 1 1 1 0 82 * : Rd=38
0E82 :                 : INT                  : 11/ 0 : A=38 F= Z0 0V   BC=00AF DE=5A51 HL=5A50 IX=F7FF IY=5C3A SP=FF4E

 FETCH 0 0 1 0 1 1 1 0 f5 * : Wd=38
 MEMWR 1 1 0 0 1 1 1 0 38 * 
 MEMWR 1 1 0 0 1 1 1 0 4c * 
0038 : F5              : PUSH AF              : 11/ 0 : A=38 F= Z0 1V   BC=00AF DE=5A51 HL=5A50 IX=F7FF IY=5C3A SP=FF4C : fail
If you look at the flags value in the final line (marked fail), you can see the F3 flags has been "corrected" from 0 to 1 based on what was PUSHed to memory. This represents reality, i.e. what the Z80 actually set them to.

The unofficial documentation says these should be based on (data + A) = (0x38 + 0x38) = 0x70. So F5 should be bit 1 and F3 should be bit 3, both 0. That how I'm calculating them. But it seems the Z80 is actually doing something different, as the value pushed shows F3 is actually 1.

My implementation of this is quite simple:

Code: Select all

   // Set the flags, see: page 16 of http://www.z80.info/zip/z80-documented.pdf
   if (reg_a >= 0) {
      int result = reg_a + arg_read;
      flag_f5 = (result >> 1) & 1;
      flag_f3 = (result >> 3) & 1;
   } else {
      flag_f5 = -1;
      flag_f3 = -1;
   }
For comparison, here's the same code from MAME:

Code: Select all

	F &= SF | ZF | CF;
	if ((A + io) & 0x02) F |= YF; /* bit 1 -> flag 5 */
	if ((A + io) & 0x08) F |= XF; /* bit 3 -> flag 3 */
(YF is F5 and XF is F3).

I'm sure I'm missing something here, but I can't for the life of me figure it out.

Dave
I think it would be less confusing to call bits 5 and 3 of the flags YF and XF consistently when talking about them individually. In your logs you mix letters and numbers after F= and I suggest displaying Y and X if they are 1 and spaces if they are 0, to be consistent with the other flags.

Regarding the behaviour of LDIR when interrupted, I wonder whether YF and XF come from just A or (HL), not A + (HL). Can you test this, with values that are not both 38H?

It should be possible to discover the exact behaviour of YF and XF in block instructions that are interrupted, on a Spectrum with your current test hardware. The frame time is 69888 T on the 16K/48K and 70908T on 128K/+2/+2A/+3. By using HALT, then a carefully calculated software timing loop, you should be to get an LDIR interrupt to occur when BC has any value of your choosing. (You'll need to allow for the interrupt routine time, of course.) HALT takes 4T, therefore the uncertainty of precisely when /INT goes low is 0-4T, much less than 21T length of LDIR.

User avatar
hoglet
Posts: 7487
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Z80 Protocol Decoder

Post by hoglet » Sun Aug 12, 2018 6:27 pm

TonyB wrote:
Sun Aug 12, 2018 5:36 pm
I think it would be less confusing to call bits 5 and 3 of the flags YF and XF consistently when talking about them individually. In your logs you mix letters and numbers after F= and I suggest displaying Y and X if they are 1 and spaces if they are 0, to be consistent with the other flags.
Yes, I tend to agree with that. Consider it done!
TonyB wrote:
Sun Aug 12, 2018 5:36 pm
Regarding the behaviour of LDIR when interrupted, I wonder whether YF and XF come from just A or (HL), not A + (HL). Can you test this, with values that are not both 38H?

It should be possible to discover the exact behaviour of YF and XF in block instructions that are interrupted, on a Spectrum with your current test hardware. The frame time is 69888 T on the 16K/48K and 70908T on 128K/+2/+2A/+3. By using HALT, then a carefully calculated software timing loop, you should be to get an LDIR interrupt to occur when BC has any value of your choosing. (You'll need to allow for the interrupt routine time, of course.) HALT takes 4T, therefore the uncertainty of precisely when /INT goes low is 0-4T, much less than 21T length of LDIR.
After some investigation with help from BigEd and his real Z80 Co Pro, we've determined they come from bits 13 and 11 of the PC (i.e. the address of the LDIR instruction). Plugging that knowledge into the decoder has eliminated all of the mis-predication errors:
https://github.com/hoglet67/Z80Decoder/ ... 80.c#L2104

I've also tweaked the rules for XF and YF for SCF/CCF based on what seems to be happening in reality on the different processors I have to hand:
https://github.com/hoglet67/Z80Decoder/ ... 80.c#L1594

I still have to figure out what's happening in the ST CMOS Z80, as it doesn't match either of the NMOS cases.

Dave

PS, in case you are interested, this is our test program for LDIR:

Code: Select all

   10 code%=&E000
   20 FOR I%=0 TO 3 STEP 3
   30 P%=code%
   40 [OPT I%
   50 .reg_af
   60 DEFW 0
   70 .reg_bc
   80 DEFW 0
   90 .reg_de
  100 DEFW 0
  110 .reg_hl
  120 DEFW 0
  130 .test
  140 PUSH AF
  150 DI
  160 LD HL,interrupt
  170 LD (&FFFE),HL
  180 LD HL,0
  190 LD (reg_af),HL
  200 LD (reg_bc),HL
  210 LD (reg_de),HL
  220 LD (reg_hl),HL
  230 EI
  240 .loop1
  250 POP AF
  260 LD BC,&1000
  270 LD DE,&C000
  280 LD HL,&D000
  290 LDIR
  300 PUSH AF
  310 LD HL,(reg_af)
  320 LD A,H
  330 OR L
  340 JR Z loop1
  350 POP AF
  360 DI
  370 LD HL,&FA82
  380 LD (&FFFE),HL
  390 EI
  400 RET
  410 .interrupt
  420 PUSH HL
  430 PUSH AF
  440 POP HL
  450 LD (reg_af),HL
  460 LD H,B
  470 LD L,C
  480 LD (reg_bc),HL
  490 LD H,D
  500 LD L,E
  510 LD (reg_de),HL
  520 POP HL
  530 LD (reg_hl),HL
  540 JP &FA82
  550 ]
  560 NEXT
  570 B%=&BB
  580 C%=&CC
  590 PRINT "Initializing"
  600 FOR I%=0 TO &FFF
  610 I%?&D000=I%
  620 NEXT
  630 *FX 14,4
  640 PRINT "Testing"
  650 @%=4
  660 FOR T%=0 TO 255
  670 A%=T%
  680 F%=&01
  690 CALL test
  700 PRINT "AF = "~(!reg_af AND &FFFF)"; ";
  710 PRINT "BC = "~(!reg_bc AND &FFFF)"; "; 
  720 PRINT "DE = "~(!reg_de AND &FFFF)"; ";
  730 PRINT "HL = "~(!reg_hl AND &FFFF)"; ";
  740 flags=?reg_af
  750 f5=(flags DIV 32) AND 1
  760 f3=(flags DIV 8) AND 1
  770 PRINT "f5=";f5;" f3=";f3
  780 NEXT

TonyB
Posts: 60
Joined: Sat Aug 11, 2018 6:45 pm
Contact:

Re: Z80 Protocol Decoder

Post by TonyB » Sun Aug 12, 2018 7:59 pm

hoglet wrote:
Sun Aug 12, 2018 6:27 pm
After some investigation with help from BigEd and his real Z80 Co Pro, we've determined they come from bits 13 and 11 of the PC (i.e. the address of the LDIR instruction). Plugging that knowledge into the decoder has eliminated all of the mis-predication errors:
https://github.com/hoglet67/Z80Decoder/ ... 80.c#L2104

I've also tweaked the rules for XF and YF for SCF/CCF based on what seems to be happening in reality on the different processors I have to hand:
https://github.com/hoglet67/Z80Decoder/ ... 80.c#L1594

I still have to figure out what's happening in the ST CMOS Z80, as it doesn't match either of the NMOS cases.
Unfortunately I can't access github nowadays due to authentication errors as I use an old PC. Are the links just to C code or is there more discussion there?

What you have found is new information. =D> I imagine that CPxR, INxR and OTxR operate in the same way.

The final iteration of LDIR is an LDI and therefore the two instructions have the same flags on exit. The extra machine cycle (M4) in LDIR clearly involves the ALU, which overwrites the LDI values of YF and XF with bits from PC. Is that simply a side-effect or does the ALU subtract two from PC? Using the 16-bit incrementer/decrementer to decrement PC twice would seem to be easier and faster.

Re your test code, the Z80 can do this:

Code: Select all

LD (reg_bc),BC
...
LD (reg_de),DE
Last edited by TonyB on Sun Aug 12, 2018 8:05 pm, edited 4 times in total.

User avatar
jgharston
Posts: 3209
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield
Contact:

Re: Z80 Protocol Decoder

Post by jgharston » Sun Aug 12, 2018 8:14 pm

hoglet wrote:
Sun Aug 12, 2018 6:27 pm
After some investigation with help from BigEd and his real Z80 Co Pro, we've determined they come from bits 13 and 11 of the PC (i.e. the address of the LDIR instruction).
That makes sense, as the last bit of execution done before an INT is responded to is PC=PC-2 which does PClo=PClo-2; PChi=PChi-Carry, and bit 13/11 are bit 5/3 of PChi. Almost every instruction that copies bit 7 of something to bit 7 of the flags to set the P/M flag actually copies bits 7/5/3.

I vaguely remember reading that the PC=PC-2 is done using the JR silicon stuffing an offset of &FE into the process.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

User avatar
hoglet
Posts: 7487
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Z80 Protocol Decoder

Post by hoglet » Sun Aug 12, 2018 8:18 pm

TonyB wrote:
Sun Aug 12, 2018 7:59 pm
Unfortunately I can't access github nowadays due to authentication errors as I use an old PC. Are the links just to C code or is there more discussion there?
Yes, it's just the C code for the Z80 Logic Analyzer Capture decoder that I'm working on.
TonyB wrote:
Sun Aug 12, 2018 7:59 pm
What you have found is new information. =D> I imagine that CPxR, INxR and OTxR operate in the same way.
That's encouraging to hear.

I will try to check the other instructions, but I'm thinking that:
- CPiR updates the flags (including XF and YF) with the comparison at each step
- INxR/OTxR updates the flags (including XF and YF) with B - 1 at each step.

So being interrupted would not expose anything different to this.

For some reason, LDxR is different. This is possibly because PF is coming from the incrementer (BC == 1) rather than the ALU.
TonyB wrote:
Sun Aug 12, 2018 7:59 pm
The final iteration of LDIR is an LDI, which is why the two instructions have the same flags on exit.
The extra machine cycle (M4) in LDIR clearly involves the ALU, which overwrites the LDI values of YF and XF with bits from PC. Is that simply a side-effect or does the ALU subtract two from PC? Using the 16-bit incrementer/decrementer to decrement PC twice would seem to be easier and faster.
The other thing I can't explain is why WZ is updated during LDIR (apparently it ends up at PC + 1). I think that's possible related as well.
TonyB wrote:
Sun Aug 12, 2018 7:59 pm
Re your test code, the Z80 can do this:

Code: Select all

LD (reg_bc),BC
...
LD (reg_de),DE
Ah yes, of course it can. Thanks.

Dave
Last edited by hoglet on Sun Aug 12, 2018 8:19 pm, edited 1 time in total.

User avatar
jgharston
Posts: 3209
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield
Contact:

Re: Z80 Protocol Decoder

Post by jgharston » Sun Aug 12, 2018 8:43 pm

jgharston wrote:
Sun Aug 12, 2018 8:14 pm
I vaguely remember reading that the PC=PC-2 is done using the JR silicon stuffing an offset of &FE into the process.
Ah, faulty memory, I was remembering the JR cc,-1 trick to do a conditional RST &38.

The PC=PC-2 uses the same increment/decrementer circuitry that is used for the normal 16-bit INCs and DECs and the PC increment and - where the 2 comes in - pushing and pulling from the stack which has two INCs or DECs. As the 16-bit INC/DEC circuitry has no interaction with the ULA it doesn't change any flags, so the observed flag changing effects must be a result of the test for BC=0 and there must be some sort of "leakage" through to the flags. DEC BC within a block instruction is the only time a 16-bit INC/DEC affects the flags.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

TonyB
Posts: 60
Joined: Sat Aug 11, 2018 6:45 pm
Contact:

Re: Z80 Protocol Decoder

Post by TonyB » Sun Aug 12, 2018 8:44 pm

hoglet wrote:
Sun Aug 12, 2018 8:18 pm
TonyB wrote:
Sun Aug 12, 2018 7:59 pm
What you have found is new information. =D> I imagine that CPxR, INxR and OTxR operate in the same way.
That's encouraging to hear.

I will try to check the other instructions, but I'm thinking that:
- CPiR updates the flags (including XF and YF) with the comparison at each step
- INxR/OTxR updates the flags (including XF and YF) with B - 1 at each step.

So being interrupted would not expose anything different to this.

For some reason, LDxR is different. This is possibly because PF is coming from the incrementer (BC == 1) rather than the ALU.

The other thing I can't explain is why WZ is updated during LDIR (apparently it ends up at PC + 1). I think that's possible related as well.
I wasn't very clear. My conjecture is that XF and YF will be the same for all the block instructions only when they are interrupted. XF = PC[11] and YF = PC[13] is consistent with the flags for this 16-bit subtraction: PC+2 - 2 = PC, so the ALU could be changing PC. The 16-bit inc/dec is used for HL, DE and BC in LDx and in theory should be available during the extra 5T in LDxR but perhaps it isn't.

What is the source of the WZ info?
Last edited by TonyB on Sun Aug 12, 2018 8:45 pm, edited 1 time in total.

User avatar
hoglet
Posts: 7487
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Z80 Protocol Decoder

Post by hoglet » Sun Aug 12, 2018 8:52 pm

TonyB wrote:
Sun Aug 12, 2018 8:44 pm
What is the source of the WZ info?
This document by Vladimir Kladov:
https://gist.github.com/drhelius/8497817

Code: Select all

MEMPTR, esoteric register of the ZiLOG Z80 CPU.
by Boo-boo (first and draft English translation by Vladimir Kladov)

  As it is known, after the instruction BIT n,(HL) execution, bits 3 and 5 of the flag register become containing values that is not documented in the official documentation at all. Actually these bits are copied from the bits 11 and 13 of the internal register pair of Z80 CPU, which is used for 16-bit operations, and in most cases to handle addresses. This is usual practice for processors having 8-bits data bus working with 16-bits data.
  It is not known why and how these bits of the internal buffer register are copied to the flags register though. At least Sean Young in the "Undocumented Z80 Documented" refers to that phenomenon (http://www.myquest.nl/z80undocumented/) and a bit more info can be found in the Z80 description of another "nocash" project (http://www.work.de/nocash/zxdocs.htm) where such register pair is called as MEMPTR. Unfortunately until now attemts to crack the algorithm setting the value of the MEMPTR by different processor instructions on base of knowning only two bits of those 16-bits register were not successful.
  But miraculously in result of many experiments (based on the hyposesis that index addressing instructions initialize the MEMPTR always the same way) and also after the deep meditations under the results of these samples we have found that CPI instruction increments the MEMPTR by 1 whereas CPD instruction decrements it. Hence, decrementing the MEMPTR in the loop and monitoring borrow from the high bits having two known bits in the flag register, it is possible to determine unambigously 14 low bits of the MEMPTR and having these in our hands to say for sure on which rule MEMPTR is set after each instruction.
  A list of instructions changing the MEMPTR is follow, together with the formula for new MEMPTR value. Here "rp" means register pair (16 bits register BC, DE, HL or SP - ?), and "INDEX" means register pair IX or IY. Instructions not listed below do not affect MEMPTR as it is found. All the CPU chips tested give the same results except KP1858BM1 and T34BM1 slices noted as "BM1" in the text.
====================================================================================

LD A,(addr)
	MEMPTR = addr + 1

LD (addr),A
	MEMPTR_low = (addr + 1) & #FF,  MEMPTR_hi = A
	Note for *BM1: MEMPTR_low = (addr + 1) & #FF,  MEMPTR_hi = 0

LD A,(rp)  where rp -- BC or DE
	MEMPTR = rp + 1

LD (rp),A  where rp -- BC or DE
	MEMPTR_low = (rp + 1) & #FF,  MEMPTR_hi = A
	Note for *BM1: MEMPTR_low = (rp + 1) & #FF,  MEMPTR_hi = 0

LD (addr), rp
LD rp,(addr)
	MEMPTR = addr + 1

EX (SP),rp
	MEMPTR = rp value after the operation

ADD/ADC/SBC rp1,rp2
	MEMPTR = rp1_before_operation + 1

RLD/RRD
	MEMPTR = HL + 1

JR/DJNZ/RET/RETI/RST (jumping to addr)
	MEMPTR = addr

JP(except JP rp)/CALL addr (even in case of conditional call/jp, independantly on condition satisfied or not)
	MEMPTR = addr

IN A,(port)
	MEMPTR = (A_before_operation << 8) + port + 1

IN A,(C)
	MEMPTR = BC + 1

OUT (port),A
	MEMPTR_low = (port + 1) & #FF,  MEMPTR_hi = A
	Note for *BM1: MEMPTR_low = (port + 1) & #FF,  MEMPTR_hi = 0

OUT (C),A
	MEMPTR = BC + 1

LDIR/LDDR
	when BC == 1: MEMPTR is not changed
	when BC <> 1: MEMPTR = PC + 1, where PC = instruction address

CPI
	MEMPTR = MEMPTR + 1

CPD
	MEMPTR = MEMPTR - 1

CPIR
	when BC=1 or A=(HL): exactly as CPI
	In other cases MEMPTR = PC + 1 on each step, where PC = instruction address.
	Note* since at the last execution BC=1 or A=(HL), resulting MEMPTR = PC + 1 + 1 
	  (if there were not interrupts during the execution) 

CPDR
	when BC=1 or A=(HL): exactly as CPD
	In other cases MEMPTR = PC + 1 on each step, where PC = instruction address.
	Note* since at the last execution BC=1 or A=(HL), resulting MEMPTR = PC + 1 - 1 
	  (if there were not interrupts during the execution)

INI
	MEMPTR = BC_before_decrementing_B + 1

IND
	MEMPTR = BC_before_decrementing_B - 1

INIR
	exactly as INI on each execution.
	I.e. resulting MEMPTR = ((1 << 8) + C) + 1 

INDR
	exactly as IND on each execution.
	I.e. resulting MEMPTR = ((1 << 8) + C) - 1 

OUTI
	MEMPTR = BC_after_decrementing_B + 1

OUTD
	MEMPTR = BC_after_decrementing_B - 1

OTIR
	exactly as OUTI on each execution. I.e. resulting MEMPTR = C + 1 

OTDR
	exactly as OUTD on each execution. I.e. resulting MEMPTR = C - 1

Any instruction with (INDEX+d):
	MEMPTR = INDEX+d

Interrupt call to addr:
	As usual CALL. I.e. MEMPTR = addr

====================================================================================
  What is the profit of which secret knowledge? First of all, it is possible now to program Z80 emulators supporting _all_ the undocumented pecularities of the CPU. In the second place the fact that on some Z80 clones MEMPTR register behaves a bit another adds a method of model checking. Seems very enough!
(c)2006, zx.pk.ru
Theoretical part: boo_boo, Vladimir Kladov
Testing real Z80 chips: Wlodek, CHRV, icebear, molodcov_alex, goodboy
LDIR/LDDR
when BC == 1: MEMPTR is not changed
when BC <> 1: MEMPTR = PC + 1, where PC = instruction address

So this implies MEMPTR is involved during cycle 17-21 when the PC is decremented, but not elsewhere.

TonyB
Posts: 60
Joined: Sat Aug 11, 2018 6:45 pm
Contact:

Re: Z80 Protocol Decoder

Post by TonyB » Sun Aug 12, 2018 9:07 pm

hoglet wrote:
Sun Aug 12, 2018 8:52 pm
TonyB wrote:
Sun Aug 12, 2018 8:44 pm
What is the source of the WZ info?
This document by Vladimir Kladov: <snip>

LDIR/LDDR
when BC == 1: MEMPTR is not changed
when BC <> 1: MEMPTR = PC + 1, where PC = instruction address

So this implies MEMPTR is involved during cycle 17-21 when the PC is decremented, but not elsewhere.
Thanks, I have a copy of the MEMPTR info that I'd forgotten about. It does suggest that WZ/MEMPTR is written after the first decrement of PC+2 by the 16-bit decrementer and that the ALU flags are a side-effect. Apologies for the insulting question, but did you test LDIR at address xxFE or xxFF?

User avatar
hoglet
Posts: 7487
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Z80 Protocol Decoder

Post by hoglet » Sun Aug 12, 2018 9:13 pm

TonyB wrote:
Sun Aug 12, 2018 9:07 pm
Apologies for the insulting question, but did you test LDIR at address xxFE or xxFF?
Not insulting at all! After all, I'm pretty new to the Z80.

Yes, earlier today BigEd ran the test and adjusted code% so that the LDIR fell at: &9FFD, &9FFE, &9FFF and &A000 in turn.

At &9FFD, &9FFE, &9FFF, f5/f3 were 0/1.

At &A000, f5/f3 were 1/0.

We plan to double check this tomorrow, and maybe try a few brands of Z80.

Dave

TonyB
Posts: 60
Joined: Sat Aug 11, 2018 6:45 pm
Contact:

Re: Z80 Protocol Decoder

Post by TonyB » Sun Aug 12, 2018 9:26 pm

hoglet wrote:
Sun Aug 12, 2018 9:13 pm
TonyB wrote:
Sun Aug 12, 2018 9:07 pm
Apologies for the insulting question, but did you test LDIR at address xxFE or xxFF?
Not insulting at all! After all, I'm pretty new to the Z80.

Yes, earlier today BigEd ran the test and adjusted code% so that the LDIR fell at: &9FFD, &9FFE, &9FFF and &A000 in turn.

At &9FFD, &9FFE, &9FFF, f5/f3 were 0/1.

At &A000, f5/f3 were 1/0.

We plan to double check this tomorrow, and maybe try a few brands of Z80.

Dave
Thanks for the info. Perhaps you could check MEMPTR too, on a Zilog Z80?

User avatar
hoglet
Posts: 7487
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Z80 Protocol Decoder

Post by hoglet » Sun Aug 12, 2018 9:43 pm

TonyB wrote:
Sun Aug 12, 2018 9:26 pm
[Thanks for the info. Perhaps you could check MEMPTR too, on a Zilog Z80?
The tests so far on the Z80 Co Pro have used a SGS Z8400BB1 Z80B CPU (6MHz) datecode 88346.

When you say check MEMPTR, what do you mean exactly?

i.e. Attempt to validate the info in that document, or something more specific?

User avatar
Elminster
Posts: 3070
Joined: Wed Jun 20, 2012 8:09 am
Location: Essex, UK
Contact:

Re: Z80 Protocol Decoder

Post by Elminster » Sun Aug 12, 2018 9:56 pm

I got a bit lost on the thread as so many others to follow, but my rc2014 was a Zilog Z84C0010PEG z80 if anyone needs me to check anything. If already have one of those for testing then it lets me off the hook!

User avatar
hoglet
Posts: 7487
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Z80 Protocol Decoder

Post by hoglet » Sun Aug 12, 2018 10:14 pm

Elminster wrote:
Sun Aug 12, 2018 9:56 pm
I got a bit lost on the thread as so many others to follow, but my rc2014 was a Zilog Z84C0010PEG z80 if anyone needs me to check anything. If already have one of those for testing then it lets me off the hook!
Mostly of the last few days has been a deep dive into some of the undocumented aspects of the Z80, that are in fact visible and can (and do) get flagged up as suspicious by the decoder.

The Z84C0010PEG is available new from Farnell for £3.82, so I'll add one to my next order.
http://uk.farnell.com/zilog/z84c0010peg ... dp/1081891

I am interested in how the CMOS Z80s differ from the NMOS ones - so far there is the "bug" in OUT (C),0 and differences in the XF and YF flags after SCF and CCF. But that was with a ST CMOS Z80, not a Zilog one.

Dave

User avatar
Elminster
Posts: 3070
Joined: Wed Jun 20, 2012 8:09 am
Location: Essex, UK
Contact:

Re: Z80 Protocol Decoder

Post by Elminster » Sun Aug 12, 2018 10:23 pm

Yep I bought my z80 new after blowing up the last one when I accidently put 12volts through it, they don’t like that.

TonyB
Posts: 60
Joined: Sat Aug 11, 2018 6:45 pm
Contact:

Re: Z80 Protocol Decoder

Post by TonyB » Sun Aug 12, 2018 10:50 pm

hoglet wrote:
Sun Aug 12, 2018 9:43 pm
TonyB wrote:
Sun Aug 12, 2018 9:26 pm
[Thanks for the info. Perhaps you could check MEMPTR too, on a Zilog Z80?
The tests so far on the Z80 Co Pro have used a SGS Z8400BB1 Z80B CPU (6MHz) datecode 88346.

When you say check MEMPTR, what do you mean exactly?

i.e. Attempt to validate the info in that document, or something more specific?
SGS CPU is fine as that's a genuine Zilog second-source. Re MEMPTR, I mean validating just the LDIR behaviour in the document, if possible. I think the tricky bit is making sure WZ is not used between the interrupted LDIR and BIT x,(HL), which rules out IM 2.
Last edited by TonyB on Sun Aug 12, 2018 11:23 pm, edited 2 times in total.

Coeus
Posts: 1020
Joined: Mon Jul 25, 2016 11:05 am
Contact:

Re: Z80 Protocol Decoder

Post by Coeus » Sun Aug 12, 2018 10:54 pm

hoglet wrote:
Sun Aug 12, 2018 8:52 pm
So this implies MEMPTR is involved during cycle 17-21 when the PC is decremented, but not elsewhere.
Would you know if it was used before that? Surely the flags are only available to inspect at the end of the instruction so only the last use of MEMPTR within an instruction is visible.

User avatar
hoglet
Posts: 7487
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Z80 Protocol Decoder

Post by hoglet » Mon Aug 13, 2018 5:36 am

Tony,
TonyB wrote:
Sun Aug 12, 2018 10:50 pm
Re MEMPTR, I mean validating just the LDIR behaviour in the document, if possible. I think the tricky bit is making sure WZ is not used between the interrupted LDIR and BIT x,(HL), which rules out IM 2.
It sounds like you have better documentation about MEMPTR than I have.

The document I have is not specific about the interrupt mode:

Code: Select all

Interrupt call to addr:
	As usual CALL. I.e. MEMPTR = addr
Is your information publicly available somewhere?

It should be possible to temporarily use IM 1 in the Acorn Z80 Co Pro. RST &38 is used for the error handler, but could be borrowed for a while. But are you sure IM 1 doesn't also use MEMPTR (as the RST instrucion seems to)?

Dave

User avatar
hoglet
Posts: 7487
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: Z80 Protocol Decoder

Post by hoglet » Mon Aug 13, 2018 5:41 am

Coeus wrote:
Sun Aug 12, 2018 10:54 pm
hoglet wrote:
Sun Aug 12, 2018 8:52 pm
So this implies MEMPTR is involved during cycle 17-21 when the PC is decremented, but not elsewhere.
Would you know if it was used before that? Surely the flags are only available to inspect at the end of the instruction so only the last use of MEMPTR within an instruction is visible.
The documentation I have says:

Code: Select all

LDIR/LDDR
	when BC == 1: MEMPTR is not changed
	when BC <> 1: MEMPTR = PC + 1, where PC = instruction address
The first line is the 16 cycle case, the second line is the 21 cycle case. This suggests the MEMPTR is only used when decrementing the PC.

Also, LDI/LDD on their own don't change MEMPTR.

My only reference for all this is:
https://gist.github.com/drhelius/8497817

Dave

TonyB
Posts: 60
Joined: Sat Aug 11, 2018 6:45 pm
Contact:

Re: Z80 Protocol Decoder

Post by TonyB » Mon Aug 13, 2018 3:37 pm

hoglet wrote:
Mon Aug 13, 2018 5:36 am
Tony,
TonyB wrote:
Sun Aug 12, 2018 10:50 pm
Re MEMPTR, I mean validating just the LDIR behaviour in the document, if possible. I think the tricky bit is making sure WZ is not used between the interrupted LDIR and BIT x,(HL), which rules out IM 2.
It sounds like you have better documentation about MEMPTR than I have.

The document I have is not specific about the interrupt mode:

Code: Select all

Interrupt call to addr:
	As usual CALL. I.e. MEMPTR = addr
Is your information publicly available somewhere?

It should be possible to temporarily use IM 1 in the Acorn Z80 Co Pro. RST &38 is used for the error handler, but could be borrowed for a while. But are you sure IM 1 doesn't also use MEMPTR (as the RST instrucion seems to)?

Dave
I mentioned IM 2 only because it involves indirect addressing and must write WZ. The Memptr doc says RST writes WZ and IM 1 does a RST 38H. It also says an interrupt call to an address changes WZ and this could be intended to refer to IM 2. Anyway, it seems that both IM 2 and IM 1 destroy the previous value of WZ.

This still leaves IM 0, which could be used with a little bit of circuitry. The best opcode to put on the data bus during the interrupt acknowledge cycle is E9H for JP (HL) as this does not modify WZ, according to the doc. Incidentally, this is a good example of why the instruction mnemonic should be JP HL. If the addressing were indirect then WZ would be overwritten. E9H = 11101001B, so D1/2/4 must be low when /IORQ and /M1 are low.

I don't know anything about the Acorn Z80 Co Pro. Are there pull-up resistors on the data bus, or does is it just float high? Checking WZ by using BIT x,(HL) is additional to testing the flags when block instructions are interrupted and I could understand if you don't feel inclined to do it.

I think there is a way to find out what the flags are at the end of every machine cycle, so that one could see how the flags change or not during instructions with multiple M cycles. The method might also expose WZ at the same time. It requires a small PLD, a GAL22V10 would do the job and maybe only a 16V8, but it does not use any interrupts.
Last edited by TonyB on Thu Aug 30, 2018 7:56 pm, edited 5 times in total.

TonyB
Posts: 60
Joined: Sat Aug 11, 2018 6:45 pm
Contact:

Re: Z80 Protocol Decoder

Post by TonyB » Mon Aug 13, 2018 4:47 pm

I've had a look at the original Z80 2nd processor and it can't be modified easily.

User avatar
BigEd
Posts: 2091
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Z80 Protocol Decoder

Post by BigEd » Mon Aug 13, 2018 4:57 pm

I'm intrigued - what's the idea? Easy enough if the z80 has something between itself and the socket?

TonyB
Posts: 60
Joined: Sat Aug 11, 2018 6:45 pm
Contact:

Re: Z80 Protocol Decoder

Post by TonyB » Mon Aug 13, 2018 5:04 pm

BigEd wrote:
Mon Aug 13, 2018 4:57 pm
I'm intrigued - what's the idea? Easy enough if the z80 has something between itself and the socket?
If the Z80 were removed and replaced by a PCB or prototype board with a Z80 and a GAL then it should work. What does the I/O map look like? I need a single write port.
Last edited by TonyB on Mon Aug 13, 2018 5:06 pm, edited 1 time in total.

TonyB
Posts: 60
Joined: Sat Aug 11, 2018 6:45 pm
Contact:

Re: Z80 Protocol Decoder

Post by TonyB » Mon Aug 13, 2018 5:12 pm

TonyB wrote:
Mon Aug 13, 2018 5:04 pm
BigEd wrote:
Mon Aug 13, 2018 4:57 pm
I'm intrigued - what's the idea? Easy enough if the z80 has something between itself and the socket?
If the Z80 were removed and replaced by a PCB or prototype board with a Z80 and a GAL then it should work. What does the I/O map look like? I need a single write port.
Is there a decent circuit diagram anywhere? I'm using one that is spread over two pages.

Post Reply