Z80 Protocol Decoder

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

Z80 Protocol Decoder

Post by hoglet » Sat Aug 04, 2018 5:13 pm

Hi Guys,

Slightly off-topic for stardot, but I know we have plenty of Z80 folk on here.

Mostly as an excuse to learn a bit more about the Z80, I've started work on a Z80 Protocol Decoder:
https://github.com/hoglet67/Z80Decoder/

This takes the same approach as I took with the 6502 Protocol Decoder, specifically:
- written in C, so it's fast and in principle quite portable
- works against a raw capture file from a 16-bit logic analyzer, using DATA, M1, RD, WR, MREQ, IORQ
- capturing synchronously on the rising edge of Phi, or asynchronously at 12MHz
- runs a full Z80 emulation including all the undocumented flags and the internal memptr/MZ register
- produces nice instruction level traces, including all the register values

Here's a photo of the cheap (£12) analyzer hooked up to a ZX81:
IMG_1423.JPG
And here's a fragment of the output from from the decoder (just showing instructions and processor state):

Code: Select all

0A6B : EB              : EX DE,HL             :  3 : A=FF F=  0 0    BC=0004 DE=4096 HL=4099 IX=0281 IY=4000 IR=1E13 M=0A6B SP=43FA
0A6C : E1              : POP HL               : 11 : A=FF F=  0 0    BC=0004 DE=4096 HL=0000 IX=0281 IY=4000 IR=1E14 M=0A6B SP=43FC
0A6D : 19              : ADD HL,DE            :  3 : A=FF F=  0 0    BC=0004 DE=4096 HL=4096 IX=0281 IY=4000 IR=1E15 M=0001 SP=43FC
0A6E :                 : NMI                  : 30 : A=FF F=  0 0    BC=0004 DE=4096 HL=4096 IX=0281 IY=4000 IR=1E17 M=0066 SP=43FA
0066 : 08              : EX AF,AF'            :  3 : A=FE F=S 1 1  C BC=0004 DE=4096 HL=4096 IX=0281 IY=4000 IR=1E18 M=0066 SP=43FA
0067 : 3C              : INC A                :  4 : A=FF F=S 1 1  C BC=0004 DE=4096 HL=4096 IX=0281 IY=4000 IR=1E19 M=0066 SP=43FA
0068 : FA 6D 00        : JP M,006Dh           : 11 : A=FF F=S 1 1  C BC=0004 DE=4096 HL=4096 IX=0281 IY=4000 IR=1E1A M=006D SP=43FA
006D : 08              : EX AF,AF'            :  3 : A=FF F=  0 0    BC=0004 DE=4096 HL=4096 IX=0281 IY=4000 IR=1E1B M=006D SP=43FA
006E : C9              : RET                  : 11 : A=FF F=  0 0    BC=0004 DE=4096 HL=4096 IX=0281 IY=4000 IR=1E1C M=0A6E SP=43FC
0A6E : D5              : PUSH DE              : 11 : A=FF F=  0 0    BC=0004 DE=4096 HL=4096 IX=0281 IY=4000 IR=1E1D M=0A6E SP=43FA
0A6F : ED B0           : LDIR                 : 14 : A=FF F=  1 1V   BC=0003 DE=4097 HL=4097 IX=0281 IY=4000 IR=1E1F M=0A70 SP=43FA
0A6F : ED B0           : LDIR                 : 21 : A=FF F=  1 1V   BC=0002 DE=4098 HL=4098 IX=0281 IY=4000 IR=1E21 M=0A70 SP=43FA
0A6F : ED B0           : LDIR                 : 21 : A=FF F=  0 0V   BC=0001 DE=4099 HL=4099 IX=0281 IY=4000 IR=1E23 M=0A70 SP=43FA
0A6F : ED B0           : LDIR                 : 21 : A=FF F=  1 1    BC=0000 DE=409A HL=409A IX=0281 IY=4000 IR=1E25 M=0A70 SP=43FA
0A71 : E1              : POP HL               : 12 : A=FF F=  1 1    BC=0000 DE=409A HL=4096 IX=0281 IY=4000 IR=1E26 M=0A70 SP=43FC
0A72 : C9              : RET                  : 10 : A=FF F=  1 1    BC=0000 DE=409A HL=4096 IX=0281 IY=4000 IR=1E27 M=048D SP=43FE
048D : 2A 14 40        : LD HL,(4014h)        : 16 : A=FF F=  1 1    BC=0000 DE=409A HL=4097 IX=0281 IY=4000 IR=1E28 M=4015 SP=43FE
0490 : FD 36 00 FF     : LD (IY+0),ffh        : 19 : A=FF F=  1 1    BC=0000 DE=409A HL=4097 IX=0281 IY=4000 IR=1E2A M=4000 SP=43FE
0494 : CD 66 07        : CALL 0766h           : 32 : A=FF F=  1 1    BC=0000 DE=409A HL=4097 IX=0281 IY=4000 IR=1E2B M=0766 SP=43FC
0766 :                 : NMI                  : 11 : A=FF F=  1 1    BC=0000 DE=409A HL=4097 IX=0281 IY=4000 IR=1E2D M=0066 SP=43FA
0066 : 08              : EX AF,AF'            :  3 : A=FF F=S 1 1  C BC=0000 DE=409A HL=4097 IX=0281 IY=4000 IR=1E2E M=0066 SP=43FA
0067 : 3C              : INC A                :  4 : A=00 F= Z0H0  C BC=0000 DE=409A HL=4097 IX=0281 IY=4000 IR=1E2F M=0066 SP=43FA
0068 : FA 6D 00        : JP M,006Dh           : 11 : A=00 F= Z0H0  C BC=0000 DE=409A HL=4097 IX=0281 IY=4000 IR=1E30 M=006D SP=43FA
006B : 28 02           : JR Z,006Fh           :  7 : A=00 F= Z0H0  C BC=0000 DE=409A HL=4097 IX=0281 IY=4000 IR=1E31 M=006F SP=43FA
006F : 08              : EX AF,AF'            :  8 : A=FF F=  1 1    BC=0000 DE=409A HL=4097 IX=0281 IY=4000 IR=1E32 M=006F SP=43FA
0070 : F5              : PUSH AF              : 12 : A=FF F=  1 1    BC=0000 DE=409A HL=4097 IX=0281 IY=4000 IR=1E33 M=006F SP=43F8
0071 : C5              : PUSH BC              : 11 : A=FF F=  1 1    BC=0000 DE=409A HL=4097 IX=0281 IY=4000 IR=1E34 M=006F SP=43F6
0072 : D5              : PUSH DE              : 11 : A=FF F=  1 1    BC=0000 DE=409A HL=4097 IX=0281 IY=4000 IR=1E35 M=006F SP=43F4
0073 : E5              : PUSH HL              : 11 : A=FF F=  1 1    BC=0000 DE=409A HL=4097 IX=0281 IY=4000 IR=1E36 M=006F SP=43F2
0074 : 2A 0C 40        : LD HL,(400Ch)        : 16 : A=FF F=  1 1    BC=0000 DE=409A HL=407D IX=0281 IY=4000 IR=1E37 M=400D SP=43F2
0077 : CB FC           : SET 7,H              :  7 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E39 M=400D SP=43F2
0079 : 76              : HALT                 :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E3A M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E3C M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E3E M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E40 M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E42 M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E44 M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E46 M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E48 M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E4A M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E4C M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E4E M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E50 M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E52 M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E54 M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E56 M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E58 M=400D SP=43F2
007A :                 : NOP                  :  4 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E5A M=400D SP=43F2
007A :                 : NMI                  : 25 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E5C M=0066 SP=43F0
0066 : 08              : EX AF,AF'            :  3 : A=00 F= Z0H0  C BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E5D M=0066 SP=43F0
0067 : 3C              : INC A                :  4 : A=01 F=  0 0  C BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E5E M=0066 SP=43F0
0068 : FA 6D 00        : JP M,006Dh           : 11 : A=01 F=  0 0  C BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E5F M=006D SP=43F0
006B : 28 02           : JR Z,006Fh           :  7 : A=01 F=  0 0  C BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E60 M=006D SP=43F0
006D : 08              : EX AF,AF'            :  3 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E61 M=006D SP=43F0
006E : C9              : RET                  : 11 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E62 M=007A SP=43F2
007A : D3 FD           : OUT (FDh),A          : 11 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E63 M=FFFE SP=43F2
007C : DD E9           : JP (IX)              :  7 : A=FF F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E65 M=FFFE SP=43F2
0281 : ED 5F           : LD A,R               :  8 : A=67 F=  1 1    BC=0000 DE=409A HL=C07D IX=0281 IY=4000 IR=1E67 M=FFFE SP=43F2
0283 : 01 01 19        : LD BC,1901h          : 12 : A=67 F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1E68 M=FFFE SP=43F2
0286 : 3E F5           : LD A,F5h             :  7 : A=F5 F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1E69 M=FFFE SP=43F2
0288 : CD B5 02        : CALL 02B5h           : 17 : A=F5 F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1E6A M=02B5 SP=43F0
02B5 : ED 4F           : LD R,A               :  7 : A=F5 F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1EF5 M=02B5 SP=43F0
02B7 : 3E DD           : LD A,DDh             :  9 : A=DD F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1EF6 M=02B5 SP=43F0
02B9 : FB              : EI                   :  3 : A=DD F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1EF7 M=02B5 SP=43F0
02BA : E9              : JP (HL)              :  4 : A=DD F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1EF8 M=02B5 SP=43F0
C07D : 76              : HALT                 :  4 : A=DD F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1EF9 M=02B5 SP=43F0
C07E :                 : NOP                  :  4 : A=DD F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1EFB M=02B5 SP=43F0
C07E :                 : NOP                  :  4 : A=DD F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1EFD M=02B5 SP=43F0
C07E :                 : NOP                  :  4 : A=DD F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1EFF M=02B5 SP=43F0
C07E :                 : NOP                  :  4 : A=DD F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1E81 M=02B5 SP=43F0
C07E :                 : NOP                  :  4 : A=DD F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1E83 M=02B5 SP=43F0
C07E :                 : NOP                  :  4 : A=DD F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1E85 M=02B5 SP=43F0
C07E :                 : NOP                  :  4 : A=DD F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1E87 M=02B5 SP=43F0
C07E :                 : NOP                  :  4 : A=DD F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1E89 M=02B5 SP=43F0
C07E :                 : INT                  : 14 : A=DD F=  1 1    BC=1901 DE=409A HL=C07D IX=0281 IY=4000 IR=1E8B M=0038 SP=43EE
0038 : 0D              : DEC C                :  3 : A=DD F= Z0 0 N  BC=1900 DE=409A HL=C07D IX=0281 IY=4000 IR=1E8C M=0038 SP=43EE
0039 : C2 45 00        : JP NZ,0045h          : 11 : A=DD F= Z0 0 N  BC=1900 DE=409A HL=C07D IX=0281 IY=4000 IR=1E8D M=0045 SP=43EE
003C : E1              : POP HL               : 10 : A=DD F= Z0 0 N  BC=1900 DE=409A HL=C07E IX=0281 IY=4000 IR=1E8E M=0045 SP=43F0
003D : 05              : DEC B                :  3 : A=DD F=  0 1 N  BC=1800 DE=409A HL=C07E IX=0281 IY=4000 IR=1E8F M=0045 SP=43F0
003E : C8              : RET Z                :  8 : A=DD F=  0 1 N  BC=1800 DE=409A HL=C07E IX=0281 IY=4000 IR=1E90 M=0045 SP=43F0
003F : CB D9           : SET 3,C              :  4 : A=DD F=  0 1 N  BC=1808 DE=409A HL=C07E IX=0281 IY=4000 IR=1E92 M=0045 SP=43F0
0041 : ED 4F           : LD R,A               :  8 : A=DD F=  0 1 N  BC=1808 DE=409A HL=C07E IX=0281 IY=4000 IR=1EDD M=0045 SP=43F0
0043 : FB              : EI                   :  5 : A=DD F=  0 1 N  BC=1808 DE=409A HL=C07E IX=0281 IY=4000 IR=1EDE M=0045 SP=43F0
0044 : E9              : JP (HL)              :  4 : A=DD F=  0 1 N  BC=1808 DE=409A HL=C07E IX=0281 IY=4000 IR=1EDF M=0045 SP=43F0
C07E : 76              : HALT                 :  4 : A=DD F=  0 1 N  BC=1808 DE=409A HL=C07E IX=0281 IY=4000 IR=1EE0 M=0045 SP=43F0
C07F :                 : NOP                  :  4 : A=DD F=  0 1 N  BC=1808 DE=409A HL=C07E IX=0281 IY=4000 IR=1EE2 M=0045 SP=43F0
C07F :                 : NOP                  :  4 : A=DD F=  0 1 N  BC=1808 DE=409A HL=C07E IX=0281 IY=4000 IR=1EE4 M=0045 SP=43F0
One of the things I struggled with was recognising that an NMI was being handled, as there isn't any kind of explicit NMI acknowledge cycle indication. It was also interesting so see the ZX81 makes use of HALT.

The full output file is here:
https://www.dropbox.com/s/ves5gcg0p2zmkkk/zx81.zip?dl=0

Much more testing of this is needed. There's a certain amount of self-checking built into the emulator. For example, when a register is written to memory, we check the emulated value against what is seen on the bus, and flag an error if they don't match. I'm sure I'll find many more errors if I try running some of the Z80 test suites. I was planning to try this one written by Patrick Rak:
https://www.worldofspectrum.org/forums/ ... nt/668711/

My collection of Z80 machines is quite limited, just a ZX81 and a couple of Spectrums. It would be great to have some traces from some other machines, if anyone feels like helping out. :D

The above ZX81 trace is error free. The Spectrum +2 trace has just 3 errors (all the same, relating to the undocumented f5/f3 flags when an LDIR is interrupted). I've been using this as my reference for all the undocumented behaviour:
http://www.z80.info/zip/z80-documented.pdf

Dave

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

Re: Z80 Protocol Decoder

Post by jgharston » Sat Aug 04, 2018 5:23 pm

hoglet wrote:
Sat Aug 04, 2018 5:13 pm
One of the things I struggled with was recognising that an NMI was being handled, as there isn't any kind of explicit NMI acknowledge cycle indication. It was also interesting so see the ZX81 makes use of HALT.
The simplest thing might be to just monitor the NMI line.

The Z80 has an maskable interupt acknowledge cycle that sets IORQ and M1 to a normally impossible state, but there is no comparable set of signals to indicate an NMI being acknowledged, other than the fact that the NMI line has dropped, a stack push has occured, and a jump to 0066 has occured.

Code: Select all

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

User avatar
sirmorris
Posts: 744
Joined: Wed Feb 11, 2009 12:18 pm
Location: oxfordshire uk
Contact:

Re: Z80 Protocol Decoder

Post by sirmorris » Sat Aug 04, 2018 5:27 pm

This is very exciting. If I wasn't so busy I'd be looking for my LCSoft board right now. I'll be happy to help out with traces for other machines but it will be a while before I can get to a z80.

*edit*
I've written a few things for the ZX81 in my time, if you'd like the source for a game (16k required tho, m'fraid) you could compare trace vs source. There are some 1k hires games by Johan 'dr beep' Koelman which if IRC come with source too. They would be interesting because the video routines are custom written.
Last edited by sirmorris on Sat Aug 04, 2018 5:33 pm, edited 1 time in total.

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

Re: Z80 Protocol Decoder

Post by hoglet » Sat Aug 04, 2018 5:37 pm

jgharston wrote:
Sat Aug 04, 2018 5:23 pm
The Z80 has an maskable interupt acknowledge cycle that sets IORQ and M1 to a normally impossible state, but there is no comparable set of signals to indicate an NMI being acknowledged, other than the fact that the NMI line has dropped, a stack push has occured, and a jump to 0066 has occured.
The ambiguity arises when a NMI happens just before a PUSH, because the bus cycles for a normal PUSH and an NMI PUSH are identical. So it's not easy to tell which took place.

At the moment I'm making use of the emulated program counter (PC) value, so if I see a PUSH of the current PC, I'm assuming that an is NMI taking place. This actually seems to work well in practice, though clearly false positives are possible, and more likely if you don't actually monitor NMI.

(For some reason my logic analyzer is not reliably capturing NMI - I need to get the scope out an check the levels)

Dave
Last edited by hoglet on Sat Aug 04, 2018 5:49 pm, edited 1 time in total.

dominicbeesley
Posts: 625
Joined: Tue Apr 30, 2013 11:16 am
Contact:

Re: Z80 Protocol Decoder

Post by dominicbeesley » Sat Aug 04, 2018 6:20 pm

Kudos to you again dave.

Is this a ground up new application or a suite of processors?

I need to look at this for the 6x09...

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

Re: Z80 Protocol Decoder

Post by hoglet » Sat Aug 04, 2018 7:01 pm

dominicbeesley wrote:
Sat Aug 04, 2018 6:20 pm
Is this a ground up new application or a suite of processors?
At the moment it's seperate, because to be honest I wasn't sure how best to generalise the 6502 Decoder (which already has far to many command line options). Maybe in the future they will come together.

Dave
Last edited by hoglet on Sat Aug 04, 2018 7:02 pm, edited 3 times in total.

User avatar
1024MAK
Posts: 7787
Joined: Mon Apr 18, 2011 4:46 pm
Location: Looking forward to summer in Somerset, UK...
Contact:

Re: Z80 Protocol Decoder

Post by 1024MAK » Sat Aug 04, 2018 7:48 pm

Hi Dave

Very interesting :D

Some questions / points...
hoglet wrote:
Sat Aug 04, 2018 5:13 pm
- capturing synchronously on the rising edge of Phi, or asynchronously at 12MHz
In Z80 systems, the Z80 clock is often not normally referred to as Phi. Plus many systems don't use the Z80 clock for anything apart from clocking the CPU. Especially since the clock signal is not needed for control of any of the busses. Often, only the Zilog interface chips use it. And even they don't use it for bus control.

The ZX80 and ZX81 use /WAIT. The ZX81 uses NMI. The ZX Spectrum 16k, 48k, plus, 128k and the +2 (grey, uses a 9V PSU) have the CPU clock controlled by the ULA, so that the ULA can "pause" the CPU during the time the ULA is reading screen data.
The later Amstrad +2A, +2B (both in a black case and with a PSU that connects via a DIN connector), +3 and +3B have the CPU controlled via the /WAIT input, but don't 'stop the clock' like with earlier models. Internally, the ZX Spectrums don't use NMI. On the ZX Spectrum, HALT is often used to synchronise to the 50Hz ULA produced interrupt.

Can your decoding cope with all the tricks used in Z80 code, like the restart (RST XX) instruction immediately followed by data that will be used by the called routine?
hoglet wrote:
Sat Aug 04, 2018 5:13 pm
My collection of Z80 machines is quite limited, just a ZX81 and a couple of Spectrums. It would be great to have some traces from some other machines, if anyone feels like helping out. :D
I would offer to help, but am rather busy at the moment.
Other computers and game machines that use the Z80 include:
  • Micro-Professor MPF-I (trainer) (got)
  • Cambridge Z88 (got)
  • Amstrad NC100 (got) and NC200 (got)
  • Memotech MTX500 range (got)
  • Video Genie (Got)
  • Amstrad CPC464 (got, but still awaiting repair) and CPC6128 (got)
  • Sharp MZ-80A (got) and Sharp MZ-700 (got)
  • MSX (got one, but can't remember any details, came in a bundle with three other computers)
  • Commodore 128 (got)
  • Research Machines 380Z and 480Z (have never managed to get either of these)
  • Radio Shack TRS-80 (and various clones)
  • Osborne 1
  • ColecoVision
Plus various CP/M systems...

Whoops, forgot Jon's favourite Amstrad range, the PCW range :mrgreen:

And of course, the Sinclair range (yes, I've got one of each of the U.K. models, the 128k is another that is awaiting repair though). There are the American Timex-Sinclair machines and the European Timex-Sinclair machines (no, they are not all the same).
There are also various clones of the ZX80/ZX81 and lots and lots of clones of the ZX Spectrum.
hoglet wrote:
Sat Aug 04, 2018 5:13 pm
I've been using this as my reference for all the undocumented behaviour: http://www.z80.info/zip/z80-documented.pdf
That site is a very good resource for the Z80 :wink:
There are some other pages that give various additional details of the Z80, so keep browsing this site.

Mark
Last edited by 1024MAK on Sat Aug 04, 2018 7:49 pm, edited 1 time in total.
For a "Complete BBC Games Archive" visit www.bbcmicro.co.uk NOW!
BeebWiki‬ - for answers to many questions...

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

Re: Z80 Protocol Decoder

Post by Elminster » Sat Aug 04, 2018 8:06 pm

I of course have the z80 Powered RC2014, basically configured to bootstrap to msdos, I plan at some point to get cp/m running on it.

When I get some time I will see if I can hook it all up.

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

Re: Z80 Protocol Decoder

Post by Coeus » Sat Aug 04, 2018 8:33 pm

1024MAK wrote:
Sat Aug 04, 2018 7:48 pm
The ZX80 and ZX81 use /WAIT. The ZX81 uses NMI. The ZX Spectrum 16k, 48k, plus, 128k and the +2 (grey, uses a 9V PSU) have the CPU clock controlled by the ULA, so that the ULA can "pause" the CPU during the time the ULA is reading screen data.
Are these all ways in which the respective systems handle video output? I know the ZX81 used to the CPU to do the video output - that is how it could cope with a compressed (variable record length) screen display in which the trailing blanks on each line as well as whole trailing lines could be omitted. It makes the BBC Miro's "memory efficient" Mode 7 look extravagant.

If that NMI routine in Dave's capture is the screen display it is no wonder the machine was so slow in "compute and display" (slow) mode as it seems to get little time to do any real work.
1024MAK wrote:
Sat Aug 04, 2018 7:48 pm
Research Machines 380Z and 480Z (have never managed to get either of these)
I saw both of these (along which much else) at the National Museum of Computing on Thursday. The 380Z was just as I remembered. The 480Z's industrial design looked robust but inelegant, certain not as nice as the BBC Micro, which it was clearly intended to be an alternative to.

Anyway, another Sterling piece of work, Dave.

User avatar
1024MAK
Posts: 7787
Joined: Mon Apr 18, 2011 4:46 pm
Location: Looking forward to summer in Somerset, UK...
Contact:

Re: Z80 Protocol Decoder

Post by 1024MAK » Sat Aug 04, 2018 9:02 pm

Sorry, this is a bit off topic, but anyway...

The ZX80 and ZX81 use the CPU to collect the character code from RAM. The Z80 CPU meanwhile is fed a NOP instruction. And during the Z80 refresh cycle, the video circuitry (ZX80) / ULA (ZX81) uses the CPU to get the pixel data for the character from ROM. The video circuitry (ZX80) / ULA (ZX81) then shifts the pixel data out to the TV controlled by the pixel clock. This is repeated for each character (until the end of line marker) and at the end of the raster scan, it's repeated again for the same character row. A total of eight times (characters are 8 x 8 pixels). Then it moves onto the next character line... So yes SLOW mode (compute and display) is very slow. FAST mode (but with no screen display at all) is a bit quicker. /HALT, /WAIT, /RFSH and /INT are all used in the display system. Note that machine code programs often use their own display code, so that they can generate hi-resolution pictures.

The ZX Spectrum ULA is far more complex. This ULA needs no help from the CPU to generate the TV picture. However, to prevent the CPU from messing up reads made by the ULA to get screen data from the RAM (only the first 16k bytes of RAM, often called the 'lower RAM'), the ULA watches the CPU address lines. If it sees the CPU try to address the lower RAM when it needs access, it stops the clock to the CPU (the ULA generates the clock internally). Once the ULA has finished, the clock is restored. In the Spectrum world, this is called contended memory access or contention.

The later Amstrad machines (+2A, +2B, +3, +3B) do things differently, as they no longer use a ULA, but use a gate array designed by Amstrad. These use the CPU /WAIT pin to pause the CPU. Contended memory still exists, but the timings are different compared to the earlier machines.

Mark
For a "Complete BBC Games Archive" visit www.bbcmicro.co.uk NOW!
BeebWiki‬ - for answers to many questions...

User avatar
1024MAK
Posts: 7787
Joined: Mon Apr 18, 2011 4:46 pm
Location: Looking forward to summer in Somerset, UK...
Contact:

Re: Z80 Protocol Decoder

Post by 1024MAK » Sat Aug 04, 2018 9:08 pm

Some very useful information on the ZX80 and ZX81 available here ;)

For a more in depth explanation of the video system, read this ;)

Mark
For a "Complete BBC Games Archive" visit www.bbcmicro.co.uk NOW!
BeebWiki‬ - for answers to many questions...

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

Re: Z80 Protocol Decoder

Post by hoglet » Sat Aug 04, 2018 9:26 pm

1024MAK wrote:
Sat Aug 04, 2018 7:48 pm
In Z80 systems, the Z80 clock is often not normally referred to as Phi. Plus many systems don't use the Z80 clock for anything apart from clocking the CPU. Especially since the clock signal is not needed for control of any of the busses. Often, only the Zilog interface chips use it. And even they don't use it for bus control.

The ZX80 and ZX81 use /WAIT. The ZX81 uses NMI. The ZX Spectrum 16k, 48k, plus, 128k and the +2 (grey, uses a 9V PSU) have the CPU clock controlled by the ULA, so that the ULA can "pause" the CPU during the time the ULA is reading screen data.
The later Amstrad +2A, +2B (both in a black case and with a PSU that connects via a DIN connector), +3 and +3B have the CPU controlled via the /WAIT input, but don't 'stop the clock' like with earlier models. Internally, the ZX Spectrums don't use NMI. On the ZX Spectrum, HALT is often used to synchronise to the 50Hz ULA produced interrupt.
You raise some good points there, and I may well be about to demonstrate my lack of knowledge of the Z80, whilst simultaneously teaching several grand-people to suck eggs! My defence is the whole point of this exercise for me was to learn something new, i.e. the Z80, which I have had little contact with in the past.

A bit of background. The current Z80 Decoder is loosely based on the Z80 Protocol Decoder from sigrok, which is written in Python. My plan was to quickly port that to C, get the disassembly output working, and then add the full Z80 emulation which supports inferring the program counter, and in fact all of the other register state. I found a few issues with the bus cycle / instruction decoder, so that has been pretty much re-written from scratch, and is now a bit simpler for me to understand. So really the main part of the sigrok port that I'm still making use of is the disassembly tables.

One of the nice things about the sigrok decoder is that it identifies the "machine" cycles (Fetch, MemRd, MemWr, IORd, IOWr, IntAck) in a set of asynchronous samples without any reference to the clock. For example, the "fetch" cycle ends when the first of M1, MREQ or RD is de-asserted, and the preceding data sample is the significant one. So long as the sample clock is fast enough, this should identify the correct data, but leads to large capture files.

An alternative I have been exploring is synchronous capture, which in 6502 based systems is definitely the way to go. As you point out, that's less clear in Z80 based systems. Looking at the bus cycles is helpful here, and the tightest read timing is on the M1 instruction fetch cycle:
Z80_opcode_fetch_600.jpg
In the M1 instruction fetch cycle, the Z80 samples the read data on the rising edge at the start of T3, which is also the final rising edge where M1, MREQ and RD are all active. Because of that, when sampling off the rising edge of the clock, the same algorithm for determining the bus cycles just works. And the benefit is it has 3x less data to deal with (i.e. 4MHz rather than 12MHz)

The memory read/write cycles look a little bit different:
Z80_memory_rw_600.jpg
The slightly dodgy case with sampling on the rising edge of the clock is the Memory Rd cycle, where the Z80 samples on the falling edge in the middle of T3. So, in theory sampling on the rising edge of at the start of T3 might be too early. But my guess is that most memory systems will use the same read timing for both Fetch and MemRd cycles. That seems to be the case with the ZX81 and Spectrum +2.

It turns out sampling WAIT on the rising edge doesn't work well, for the obvious reason that the Z80 specifies it will use the falling edge. So things get a bit confusing. But actually, the decoder doesn't need to make use of WAIT. It just picks of the data at the end of the machine cycle, as determined from the other control signals. The only thing WAIT would be useful for is determining accurately the number of wait cycles vs the total cycles.
1024MAK wrote:
Sat Aug 04, 2018 7:48 pm
Can your decoding cope with all the tricks used in Z80 code, like the restart (RST XX) instruction immediately followed by data that will be used by the called routine?
It should, I think, deal with pretty much any software trick.

The only knowledge hard coded for each instruction is:
- the prefix(s)
- the opcode
- the expected number of pre/post displacement bytes
- the expected number of immediate bytes
- the number of memory/IO read cycles
- the number of memory/IO write cycles
- the endianess of multi-byte data

All of this is based on the above notion of machine cycles, rather that trying to do anything "clever" like counting individual clock cycles.

Hope this helps, and please do ask more questions!

Dave
Last edited by hoglet on Sat Aug 04, 2018 9:36 pm, edited 8 times in total.

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

Re: Z80 Protocol Decoder

Post by BigEd » Sun Aug 05, 2018 8:35 am

Great stuff Dave!

I have the communal z80 cheese wedge which you're welcome to borrow, and also likewise an NC100 and a PCW9512. But it looks like the NC100 probably has a huge SMD part, no 40-pin DIP Z80.

User avatar
1024MAK
Posts: 7787
Joined: Mon Apr 18, 2011 4:46 pm
Location: Looking forward to summer in Somerset, UK...
Contact:

Re: Z80 Protocol Decoder

Post by 1024MAK » Sun Aug 05, 2018 9:51 am

Yeah, the notebook style (NC100 and maybe the other similar computers) are likely to use SMD chips. Not had a reason to open mine.

Dave, sounds good :D.

The point I was trying to make (and I forgot/got distracted), was that as the Z80 CPU clock is not needed for bus control, it often is not available on expansion connectors. Obviously not a problem if you are picking signals off the CPU directly.

With the ZX Spectrum, using the clock that is on the expansion port is difficult due to the inconsistency between the different models for the feed to the relevant pin. And in Sinclair computers that use a Ferranti ULA, the quality of the available clock signal at the expansion port is rather poor, as it is the ULA output. The actual clock fed to the CPU is inverted via a transistor.

So if the decoding could get the state of the Z80 without needing the CPU clock, that's good. Which if I understand correctly is what you have been able to do. Which is excellent news :D =D>

I don't think the following should cause too many problems, as most fault finding normally takes place with expansions disconnected from the system. But I'll mention these anyway.
These all relate to Sinclair ZX Spectrum systems:
Some (but not many) expansions do make use of the /BUSRQ and /BUSAK.
Bank switching is common. But some of it is rather dirtier than in the Acorn systems. Because the original ROM code was not designed with bank switching in mind, when an external device wants to take control, it watches the address and control busses. When the CPU attempts to read an instruction (/M1 low) at a particular ROM address, the external device disables the internal ROM and enables it's own ROM (or RAM). So if this all happens quickly enough, the Z80 CPU is non the wiser and fetches the instruction from the external devices ROM (or RAM). As your protocol decoder can already cope with the ZX81 ULA stealing the Z80 instruction read and replacing it with the NOP op-code during the display generation routine, I don't think there will be a problem.

I remembered two more Z80 systems:
  • Jupiter Ace (I have a recreation)
  • Philips P2000C (got)
Dave, can you please remind us which analyser you are using. Earlier in the year (or was it last year) I was reading one of your previous threads where you figured out that you could decode the 6502 without having to connect to the CPU chip pins. I remember thinking that I must get hold of the device you were using, but I can't remember if I ever did :oops: #-o

Looking ahead, in a couple of weeks time, I may have some time to play...

Mark
For a "Complete BBC Games Archive" visit www.bbcmicro.co.uk NOW!
BeebWiki‬ - for answers to many questions...

cmorley
Posts: 616
Joined: Sat Jul 30, 2016 7:11 pm
Location: Oxford
Contact:

Re: Z80 Protocol Decoder

Post by cmorley » Sun Aug 05, 2018 10:07 am

1024MAK wrote:
Sun Aug 05, 2018 9:51 am
Dave, can you please remind us which analyser you are using. Earlier in the year (or was it last year) I was reading one of your previous threads where you figured out that you could decode the 6502 without having to connect to the CPU chip pins. I remember thinking that I must get hold of the device you were using, but I can't remember if I ever did :oops: #-o
Are you thinking of the Tube snoop Mark? I hacked Dave's code about to require only the 8 data bus bits & then he backported my changes (roughly) to the github version.
viewtopic.php?f=3&t=14398&hilit=tube+snoop#p191707

I think you had a PCB off me... maybe?

User avatar
1024MAK
Posts: 7787
Joined: Mon Apr 18, 2011 4:46 pm
Location: Looking forward to summer in Somerset, UK...
Contact:

Re: Z80 Protocol Decoder

Post by 1024MAK » Sun Aug 05, 2018 10:16 am

cmorley wrote:
Sun Aug 05, 2018 10:07 am
1024MAK wrote:
Sun Aug 05, 2018 9:51 am
Dave, can you please remind us which analyser you are using. Earlier in the year (or was it last year) I was reading one of your previous threads where you figured out that you could decode the 6502 without having to connect to the CPU chip pins. I remember thinking that I must get hold of the device you were using, but I can't remember if I ever did :oops: #-o
Are you thinking of the Tube snoop Mark? I hacked Dave's code about to require only the 8 data bus bits & then he backported my changes (roughly) to the github version.
viewtopic.php?f=3&t=14398&hilit=tube+snoop#p191707

I think you had a PCB off me... maybe?
That maybe it :!:
I'll try to find time to go through and check.

Thanks =D>

Mark
For a "Complete BBC Games Archive" visit www.bbcmicro.co.uk NOW!
BeebWiki‬ - for answers to many questions...

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

Re: Z80 Protocol Decoder

Post by hoglet » Sun Aug 05, 2018 10:28 am

1024MAK wrote:
Sun Aug 05, 2018 9:51 am
Some (but not many) expansions do make use of the /BUSRQ and /BUSAK.
Use of BUSRQ by a peripheral would currently mess things up.

I'm trying to limit the total number of signals to 16, which means a maximum of 8 control signals. It's mandatory to have:
- M1
- RD
- WR
- MREQ
- IORQ

Which leaves three spare. Some thoughts on the remaining ones:
- RST - useful
- NMI - useful
- BUSRQ - useful
- WAIT - might be useful in cycle count reporting
- INT - not needed (because INTACK cycle is reliable)
- BUSACK - not needed (because the response should be fairly predictable)
- REFRESH - not needed
- HALT - not needed
- CLK - not needed

So that's four signals contenting for three places.

One point of note. On the ZX81, monitoring reset is not much use. It's just an RC, and it turns out the logic threshold between the Z80 and the logic analyzer are sufficiently different that that Z80 manages to execute ~20,000 instructions before the logic analyzer sees RST go high.
1024MAK wrote:
Sun Aug 05, 2018 9:51 am
Dave, can you please remind us which analyser you are using. Earlier in the year (or was it last year) I was reading one of your previous threads where you figured out that you could decode the 6502 without having to connect to the CPU chip pins. I remember thinking that I must get hold of the device you were using, but I can't remember if I ever did :oops: #-o
For this project (and the 6502) I've been using this one:
https://hobbycomponents.com/cypress/674 ... c-analyser

It's a little fiddly to setup the software to do synchronous capture (fx2pipe), and currently this part is Linux only.

Dave

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

Re: Z80 Protocol Decoder

Post by hoglet » Sun Aug 05, 2018 10:34 am

Here's an interesting Z80 question for you....

If I run the sequence following sequence, how much would you expect A to increment by, and why?

Code: Select all

LD R,A
LD A,R
Could anyone test this?

I'm trying to verify if my emulation of the R register is correct. Here's it being used in the ZX81:

Code: Select all

C07F :                 : NOP                  :  4 : A=DD F=  0 1 N  BC=1808 DE=409A HL=C07E IX=0281 IY=4000 IR=1EFF M=0045 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 1 N  BC=1808 DE=409A HL=C07E IX=0281 IY=4000 IR=1E80 M=0045 SP=43EE
C07F :                 : NOP                  :  6 : A=DD F=  0 1 N  BC=1808 DE=409A HL=C07E IX=0281 IY=4000 IR=1E81 M=0045 SP=43EE
C07F :                 : INT                  : 11 : A=DD F=  0 1 N  BC=1808 DE=409A HL=C07E IX=0281 IY=4000 IR=1E82 M=0038 SP=43EC
0038 : 0D              : DEC C                :  4 : A=DD F=  0 0 N  BC=1807 DE=409A HL=C07E IX=0281 IY=4000 IR=1E83 M=0038 SP=43EC
0039 : C2 45 00        : JP NZ,0045h          : 10 : A=DD F=  0 0 N  BC=1807 DE=409A HL=C07E IX=0281 IY=4000 IR=1E84 M=0045 SP=43EC
0045 : D1              : POP DE               : 10 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1E85 M=0045 SP=43EE
0046 : C8              : RET Z                :  8 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1E86 M=0045 SP=43EE
0047 : 18 F8           : JR 0041h             :  8 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1E87 M=0041 SP=43EE
0041 : ED 4F           : LD R,A               :  9 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EDD M=0041 SP=43EE
0043 : FB              : EI                   :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EDE M=0041 SP=43EE
0044 : E9              : JP (HL)              :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EDF M=0041 SP=43EE
C07E : 76              : HALT                 :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EE0 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EE1 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EE2 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EE3 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EE4 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EE5 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EE6 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EE7 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EE8 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EE9 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EEA M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EEB M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EEC M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EED M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EEE M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EEF M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EF0 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EF1 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EF2 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EF3 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EF4 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EF5 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EF6 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EF7 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EF8 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EF9 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EFA M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EFB M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EFC M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EFD M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EFE M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EFF M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1E80 M=0041 SP=43EE
C07F :                 : NOP                  :  6 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1E81 M=0041 SP=43EE
C07F :                 : INT                  : 11 : A=DD F=  0 0 N  BC=1807 DE=C07F HL=C07E IX=0281 IY=4000 IR=1E82 M=0038 SP=43EC
0038 : 0D              : DEC C                :  4 : A=DD F=  0 0 N  BC=1806 DE=C07F HL=C07E IX=0281 IY=4000 IR=1E83 M=0038 SP=43EC
0039 : C2 45 00        : JP NZ,0045h          : 10 : A=DD F=  0 0 N  BC=1806 DE=C07F HL=C07E IX=0281 IY=4000 IR=1E84 M=0045 SP=43EC
0045 : D1              : POP DE               : 10 : A=DD F=  0 0 N  BC=1806 DE=C07F HL=C07E IX=0281 IY=4000 IR=1E85 M=0045 SP=43EE
0046 : C8              : RET Z                :  8 : A=DD F=  0 0 N  BC=1806 DE=C07F HL=C07E IX=0281 IY=4000 IR=1E86 M=0045 SP=43EE
0047 : 18 F8           : JR 0041h             :  8 : A=DD F=  0 0 N  BC=1806 DE=C07F HL=C07E IX=0281 IY=4000 IR=1E87 M=0041 SP=43EE
0041 : ED 4F           : LD R,A               :  9 : A=DD F=  0 0 N  BC=1806 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EDD M=0041 SP=43EE
0043 : FB              : EI                   :  4 : A=DD F=  0 0 N  BC=1806 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EDE M=0041 SP=43EE
0044 : E9              : JP (HL)              :  4 : A=DD F=  0 0 N  BC=1806 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EDF M=0041 SP=43EE
C07E : 76              : HALT                 :  4 : A=DD F=  0 0 N  BC=1806 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EE0 M=0041 SP=43EE
C07F :                 : NOP                  :  4 : A=DD F=  0 0 N  BC=1806 DE=C07F HL=C07E IX=0281 IY=4000 IR=1EE1 M=0041 SP=43EE
C07F :                 : NOP 
Dave
Last edited by hoglet on Sun Aug 05, 2018 11:29 am, edited 1 time in total.

User avatar
1024MAK
Posts: 7787
Joined: Mon Apr 18, 2011 4:46 pm
Location: Looking forward to summer in Somerset, UK...
Contact:

Re: Z80 Protocol Decoder

Post by 1024MAK » Sun Aug 05, 2018 3:46 pm

Despite what the Zilog documents say, there is actually two different resets. But outside of the world of geeks trying to use the 'special' reset, all production products use the normal reset. All resets always restart the CPU to address 0000. So I don't think there would be any need to monitor the reset pin. A lot of Z80 systems just use a R/C network, some have reset switches. Most have a time delay longer than needed (due to a recommendation from Zilog).

The question of when the R register increments (before an instruction, during an instruction or after an instruction) and what happens exactly when you use LD R,A or LD A,R has been debated for many years. The only reliable information is ironicly the operation of the refresh counter in the ZX80 / ZX81, as it is used in the display generation system (see the link I posted earlier in the thread).

I think there are some notes on z80.info about the refresh counter.

I'll have a look at your output log later on.

Mark
Last edited by 1024MAK on Sun Aug 05, 2018 3:47 pm, edited 1 time in total.
For a "Complete BBC Games Archive" visit www.bbcmicro.co.uk NOW!
BeebWiki‬ - for answers to many questions...

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

Re: Z80 Protocol Decoder

Post by BigEd » Sun Aug 05, 2018 4:57 pm

hoglet wrote:
Sun Aug 05, 2018 10:34 am
Here's an interesting Z80 question for you....

If I run the sequence following sequence, how much would you expect A to increment by, and why?

Code: Select all

LD R,A
LD A,R
Could anyone test this?
OK, hooked up the cheesewedge z80, and lo! That sequence acts as a double increment of A. Which slightly surprises me: I'd've expected both instructions to increment R, but only one of them to do it at such a time that it affects the final A.

I put a NOP in between, and as expected got an extra increment.

BBC Basic's built-in assembler for the win!

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

Re: Z80 Protocol Decoder

Post by BigEd » Sun Aug 05, 2018 5:00 pm

Hmm, I did a second load:

Code: Select all

LD R, A
LD A, R
LD A, R
and the result is A gets A+4
Last edited by BigEd on Sun Aug 05, 2018 5:02 pm, edited 1 time in total.

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

Re: Z80 Protocol Decoder

Post by hoglet » Sun Aug 05, 2018 8:21 pm

BigEd wrote:
Sun Aug 05, 2018 4:57 pm
BBC Basic's built-in assembler for the win!
Thanks for running that.

It's a somewhat surprising result, but consistent with this:
The sequence LD R,A/LD A,R increases A by two, except for the highest bit: this bit of the R register is never changed.
http://www.z80.info/zip/z80-documented.pdf

I don't really understand why it's two. All I can imaging is there is some pipelining that's complicating things.

I'll update the emulation to match.

Dave

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

Re: Z80 Protocol Decoder

Post by BigEd » Sun Aug 05, 2018 8:35 pm

The answer may be here - the only path[1] to read IR is through an incrementer:

Image

See also, perhaps, The Z-80's 16-bit increment/decrement circuit reverse engineered and generally Ken's Z80 reverse-engineering series.

[1] Edit: Oh hang on, that's not right - the diagram says you can read out of the North side onto the internal databus too. And it turns out not to be Ken's diagram. May not reflect the machine.
Last edited by BigEd on Mon Aug 06, 2018 9:58 am, edited 1 time in total.

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

Re: Z80 Protocol Decoder

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

BigEd wrote:
Sun Aug 05, 2018 8:35 pm
The answer may be here - the only path to read IR is through an incrementer:
Perfect, that explains it.

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

Re: Z80 Protocol Decoder

Post by jgharston » Sun Aug 05, 2018 10:01 pm

1024MAK wrote:
Sun Aug 05, 2018 3:46 pm
All resets always restart the CPU to address 0000. So I don't think there would be any need to monitor the reset pin.
There may be as a RESET is subtly different from JP 0.

JP 0 simply does PC=0
RESET does: all_registers=0
ie, AF/BC/DE/HL/AF'/BC'/DE'/HL'/IX/IY/SP/IR/IM/IFF/PC=0
(some documentation says that RESET sets SP=FFFF)

If your main program code sets I to nonzero then code can tell the different between JP 0/CALL 0/RST 0 and RESET by examining the I register:
0000 LD A,I
0002 AND A
0003 JR Z,IsAReset
0005 JR IsJumpToZero
...
IsAReset:
LD A,nonzero
LD I,A

Edit: and yes, there's the mythical "short reset", a RESET pulse of a single T cycle at the second T cycle of M1 sets PC=0 and nothing else - so is a hardware JP 0. Normally RESET has to be low for 6 T cycles, and normally software at location 0 treats every method of arriving there as a normal RESET.
Last edited by jgharston on Sun Aug 05, 2018 10:09 pm, edited 2 times in total.

Code: Select all

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

User avatar
1024MAK
Posts: 7787
Joined: Mon Apr 18, 2011 4:46 pm
Location: Looking forward to summer in Somerset, UK...
Contact:

Re: Z80 Protocol Decoder

Post by 1024MAK » Mon Aug 06, 2018 6:16 am

What Jonathan says about reset also changing register contents is true and I never intended to imply otherwise. In terms of decoding program flow though, for most systems, I don't think it is critical to know if the execution from 0000 was due to a reset or a jump to that address. And most of the time, we would want to know what happens between power on and an event.

Mark
For a "Complete BBC Games Archive" visit www.bbcmicro.co.uk NOW!
BeebWiki‬ - for answers to many questions...

User avatar
jonb
Posts: 2210
Joined: Sat May 21, 2011 12:42 pm
Location: South Coast of England
Contact:

Re: Z80 Protocol Decoder

Post by jonb » Mon Aug 06, 2018 6:47 am

1024MAK wrote:
Sat Aug 04, 2018 7:48 pm
Whoops, forgot Jon's favourite Amstrad range, the PCW range :mrgreen:
:lol:

Seriously, though - what a great thread! Dave, amazing stuff - where do you get the time to do all this?

Sorry for the thickie question, but is the protocol analyser like the Zicon logic analyser by any chance?
Last edited by jonb on Mon Aug 06, 2018 6:56 am, edited 1 time in total.

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

Re: Z80 Protocol Decoder

Post by hoglet » Mon Aug 06, 2018 8:08 am

jonb wrote:
Mon Aug 06, 2018 6:47 am
Sorry for the thickie question, but is the protocol analyser like the Zicon logic analyser by any chance?
Yes, in that it works as a "inverse assembler" (like Zicon and certain HP logic analyzers).

But it improves on those in two respects:
- it requires fewer connection (just the data bus and a few control signals, not the whole address bus)
- it also infers the values of all of the internal registers and flags (because it runs a Z80 emulation in parallel)

Do you have any broken Z80-based machines?

Dave
Last edited by hoglet on Mon Aug 06, 2018 8:23 am, edited 2 times in total.

User avatar
Richard Russell
Posts: 459
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Z80 Protocol Decoder

Post by Richard Russell » Mon Aug 06, 2018 9:09 am

1024MAK wrote:
Mon Aug 06, 2018 6:16 am
What Jonathan says about reset also changing register contents is true and I never intended to imply otherwise.
Many years ago I built a RAM-less Z80 system: the beacon keyer for the old GB3VHF amateur radio beacon at Wrotham in Kent. It had a Z80, a ROM, a clock oscillator/divider, two bits (I think) of output and precious little else: it definitely had no RAM of any kind. The output of the clock divider fed the CPU's reset pin, the idea being that this meant it was uncrashable - it was 'rebooted' 100 times a second or so!

The reason for the reminiscence is that the whole basis of the operation of this device was that the CPU's registers were not cleared on reset, if they had been there is no way it could ever have worked. It may be that some Z80s do, perhaps from specific manufacturers or of various design revisions, but the one I used in that device clearly didn't - and I must have known that it didn't before setting out on the design. I might even have that beacon keyer somewhere in the loft.

Richard.
Last edited by Richard Russell on Mon Aug 06, 2018 9:10 am, edited 1 time in total.

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

Re: Z80 Protocol Decoder

Post by BigEd » Mon Aug 06, 2018 9:15 am

There might well be a difference between power on and a subsequent reset: I think Ken Shirriff found that the bits which decide which of the register sets is the current one and which is the alternate are not initialised.

Post Reply