Z80 Protocol Decoder

for bbc micro/electron hardware, peripherals & programming issues (NOT emulators!)
User avatar
BigEd
Posts: 2139
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Z80 Protocol Decoder

Post by BigEd » Mon Aug 13, 2018 5:19 pm


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

Re: Z80 Protocol Decoder

Post by hoglet » Mon Aug 13, 2018 5:50 pm

TonyB wrote:
Mon Aug 13, 2018 3:37 pm
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.
The Acorn Co Pro uses IM 2 and asserts a vector of 0xFE, which is placed on the bus by IC28 (whose inputs are hard-wired). This is not socketed, so changing the value will be hard. Only the Z80 and the Tube ULA are socketed.
TonyB wrote:
Mon Aug 13, 2018 3:37 pm
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.
Interesting.... I can't imagine how this would be possible. Can you say a bit more?

Dave
Last edited by hoglet on Mon Aug 13, 2018 5:50 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 6:07 pm

BigEd wrote:
Mon Aug 13, 2018 5:19 pm
Try this:
http://mdfs.net/Info/Comp/BBC/Circuits/Tube/z80tube.gif
Many thanks.

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

Re: Z80 Protocol Decoder

Post by TonyB » Mon Aug 13, 2018 6:26 pm

hoglet wrote:
Mon Aug 13, 2018 5:50 pm
TonyB wrote:
Mon Aug 13, 2018 3:37 pm
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.
The Acorn Co Pro uses IM 2 and asserts a vector of 0xFE, which is placed on the bus by IC28 (whose inputs are hard-wired). This is not socketed, so changing the value will be hard. Only the Z80 and the Tube ULA are socketed.
TonyB wrote:
Mon Aug 13, 2018 3:37 pm
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.
Interesting.... I can't imagine how this would be possible. Can you say a bit more?

Dave
I can say more, once I have the PLD fully working in my mind. The Tube chip occupying the whole I/O map is a nuisance and the shadow ROM code would need modifying. I'll do a design for a simple standalone Z80 system first.

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

Re: Z80 Protocol Decoder

Post by TonyB » Mon Aug 13, 2018 6:28 pm

How much free space does the ROM have?

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

Re: Z80 Protocol Decoder

Post by hoglet » Mon Aug 13, 2018 6:32 pm

TonyB wrote:
Mon Aug 13, 2018 6:28 pm
How much free space does the ROM have?
Here's a disassembly:
https://acorn.huininga.nl/pub/docs/sour ... 80_120.asm

There is an obvious block from F069-F1D3 that could be re-purposed.

Dave

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

Re: Z80 Protocol Decoder

Post by jgharston » Mon Aug 13, 2018 7:53 pm

TonyB wrote:
Mon Aug 13, 2018 6:26 pm
I can say more, once I have the PLD fully working in my mind. The Tube chip occupying the whole I/O map is a nuisance and the shadow ROM code would need modifying. I'll do a design for a simple standalone Z80 system first.
If you're putting a sandwich under the Z08 then just add a bit of decoding to pass &xx0x to the Tube, and the rest is free.

Another version of the v1.20 client code source, assembleable with the Z80 assembler in Z80 BBC BASIC: http://mdfs.net/Software/Tube/Z80/ClientZ80.src

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 » Mon Aug 13, 2018 8:57 pm

Thanks for the source listings. I can actually see the second one!

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

Re: Z80 Protocol Decoder

Post by TonyB » Mon Aug 13, 2018 9:20 pm

Here's my idea for a Z80 snooper, devised today, so if it's original then you're reading about here first:

Some new hardware is needed. A socketed Z80 CPU is replaced by a board with a GAL22V10 and its own socket for the Z80.

The GAL contains a 5-bit counter, loaded by writing to an I/O address in a block of 32. If this is at 80H-9FH, say, an output to port 8FH will load the counter with 15. Z80 /IORQ is an input (named /IORQZ80) to the GAL only, which has a /IORQ output to the rest of the system that is held high when the Z80 selects the counter block. The OUT that loads the counter should be placed directly before the instruction under investigation. Using one of 32 I/O addresses for the count value avoids loading a register with it.

Once loaded, the counter decrements on the rising edge of Z80 CLK until it reaches a low value, when the GAL /BUSREQ output goes low. The Z80 responds a few T-states later at the end of the current machine cycle by taking /BUSACK low and giving up the buses. The GAL has a registered reset output (named /RESETZ80) to the Z80 only, which goes low when either the system /RESET or /BUSACK go low, at which time /BUSREQ is forced high.

This bus request mechanism and the 5-bit counter permit the Z80 to be "frozen" then immediately reset at the end of any M cycle in any instruction. The reset clears PC, I & R, disables interrupts and selects IM 0. All of the other publicly known registers are preserved, which means it is possible to see how they change inside an instruction.

With luck the internal WZ register will also be preserved. Why should it be cleared anyway? There are two T-states after reset goes high before the opcode fetch from address 0, just enough time to zero PC and the IR pair. DI and IM 0 are the result of clearing four flip-flops, which could happen during either T-state.

Note that after /BUSACK goes low the Z80 is reset but not the rest of the system. The GAL inputs and outputs are listed below.

Code: Select all

Inputs (13):
CLK
A7-A0
/WR
/IORQZ80
/BUSACK
/RESET

Outputs (9):
/IORQ
/BUSREQ
/RESETZ80
Internal registers x 6 (NC)
Last edited by TonyB on Mon Aug 13, 2018 11:09 pm, edited 8 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 10:15 pm

I think the ROM turns out to be a non-issue as only the Z80 gets reset and the Tube I/O is easy to handle, as described.

User avatar
1024MAK
Posts: 7988
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 13, 2018 10:52 pm

Interesting idea Tony 8)

Mark

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

Re: Z80 Protocol Decoder

Post by TonyB » Mon Aug 13, 2018 11:02 pm

1024MAK wrote:
Mon Aug 13, 2018 10:52 pm
Interesting idea Tony 8)

Mark
Thanks Mark. Seventh Eighth time lucky with the editing! :lol: I just need someone(s) to build and test such as device, I can provide the GAL program. There's a Z80 machine beginning with M that it would work in.
Last edited by TonyB on Mon Aug 13, 2018 11:10 pm, edited 1 time in total.

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

Re: Z80 Protocol Decoder

Post by hoglet » Tue Aug 14, 2018 7:27 am

Hi Tony,

Yes, indeed an interesting idea and thought-provoking idea.

Am I right in thinking the main advantage over any existing software approach is the ability to gain some insights into the operation of an instruction machine cycle by machine cycle?

My approach to testing the Z80 Protocol Decoder so far has been to use Patrik Rak's test suites (loaded from tape):
- Z80 Full - exercises <instruction> for pretty much all opcodes in all prefix blocks
- Z80 CCF - exercises <instruction> followed by CCF to explore how CCF behaves depending on the preceding instruction
- Z80 Memptr - exercises <instruction> followed by BIT 0,(HL) to explore how an instruction affects WZ/Memptr

These tests take about 5 minutes to run, so the capture files are large, but manageable.

Immediately after each instruction being tested, all of the register state is pushed to the stack, so the Z80 Protocol Decoder can check at this point that it's emulated state matches the target Z80 state in reality. This obviously includes the X and Y flag bits.

Yesterday BigEd and I did some coverage checks and determined that all opcodes in all prefix blocks are being exercised, with the following exceptions:
- there is no test case covering RST (by design I think)
- the test case for INDR, due to an cut-and-paste mistake, actually tests INIR a second time
- the undocumented two-byte NOPs are not exhaustively tested

Relating to WZ/Memptr, as a sanity check I commented out the updates to WZ in a few places in my decoder, specifically:
- JP nnnn
- LDI/LDD/LDIR/LDDR
and verified that after doing this, X/Y flag prediction errors were indeed seen in the Z80 Memptr tests.

So based on all this, I'm pretty happy that the Z80 Decoder is accurately tracking all the Z80 registers and flags. If there is a more targeted WZ test suite, that would be worth trying. Does such a thing exist?

Your device does sound very interesting though. Are there specific questions you would try to answer with it?

Dave
Last edited by hoglet on Tue Aug 14, 2018 7:43 am, edited 2 times in total.

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

Re: Z80 Protocol Decoder

Post by hoglet » Tue Aug 14, 2018 1:00 pm

For a bit of fun, I've written a program to work out the current value of the hidden Z80 MEMPTR register. I've read that Boo-boo and Vladimir Kladov, who made the final MEMPTR discoveries in 2006, had such a program. But I've not seen it posted anywhere.

Here's a few notes to go along with it:
- the LD A,(nnnn) instruction sets MEMPTR to nnnn + 1
- the CPI instruction increments MEMPTR
- the CPD instruction decrements MEMPTR
- BIT 0,(HL) copies MEMPTR bits 13/11 into flag register bits 5/3 - this is the only instruction where parts of MEMPTR leak
- it's only possible to work out bits 13..0 of MEMPTR, as bits 14/15 never become visible

The basic idea is keep decrementing MEMPTR (with CPD) and testing bits 13/11 with BIT 0,(HL), and do this until you observe bits 13/11 flipping from 0/0 to 1/1. The huge challenge is doing this without using any of the instructions that themselves update MEMPTR. This means the only form of branch that is possible is JP (HL).

Anyway, here's my attempt which seems to work:

(Edit: Much simpler version two posts below)

Code: Select all

   10 code%=&E000
   20 FOR I%=0 TO 3 STEP 3
   30 P%=code%
   40 [OPT I%
   50 .test
   60 DI
   70 LD A,(&0000)
   80 \ work out the value of MEMPTR without disturbing it
   90 LD DE,&FFFE
  100 CPI
  110 .loop1
  120 INC DE
  130 CPD
  140 BIT 0,(HL)
  150 PUSH AF
  160 POP BC
  170 LD A,C
  180 AND &28
  190 \ A = &00,&08,&20,&28 reflecting bits 13,11 of MEMPTR
  200 \ we want C=1 if A=&00 (to exit the loop)
  210 \ CP A,N does A-N and sets C=1 if N>A
  220 CP &01
  230 LD A,0
  240 RLA
  250 RLA
  260 RLA
  270 RLA
  280 RLA
  290 RLA
  300 LD HL, loop1
  310 ADD A,L
  320 LD L,A
  330 JP (HL)
  340 \ add NOPs so to align next block to loop12 + &20
  350 NOP
  360 NOP
  370 NOP
  380 NOP
  390 NOP
  400 NOP
  410 .loop2
  420 INC DE
  430 CPD
  440 BIT 0,(HL)
  450 PUSH AF
  460 POP BC
  470 LD A,C
  480 AND &28
  490 \ A = &00,&08,&20,&28 reflecting bits 13,11 of MEMPTR
  500 \ we want C=1 if A=&11 (to exit the loop)
  510 \ CP A,N does A-N and sets C=1 if N>A
  520 CP &21
  530 CCF
  540 LD A,0
  550 RLA
  560 RLA
  570 RLA
  580 RLA
  590 RLA
  600 RLA
  610 LD HL, loop2
  620 ADD A,L
  630 LD L,A
  640 JP (HL)
  650 \ add NOPs so to align next block to loop2 + &20
  660 NOP
  670 NOP
  680 NOP
  690 NOP
  700 NOP
  710 LD H,D
  720 LD L,E
  730 EI
  740 RET
  750 ]
  760 NEXT
  770 PRINT "Press a key to run test"
  780 Z=GET
  790 FOR X%=1 TO &10000 STEP &123
  800 test?2=(X% - 1) MOD 256
  810 test?3=(X% - 1) DIV 256
  820 Y%=USR(test) DIV &10000
  830 PRINT ~X%,~Y%
  840 IF Y%<>(X% AND &3FFF) PRINT "FAIL":END
  850 NEXT
Improvements most welcome. It would be nice to get this down to just one loop.

Thanks BigEd for the loan of the Z80 Co Pro on which this has successfully run.

Dave
Last edited by hoglet on Tue Aug 14, 2018 2:09 pm, edited 6 times in total.

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

Re: Z80 Protocol Decoder

Post by TonyB » Tue Aug 14, 2018 1:37 pm

Hello Dave,

Thanks for the detailed reply to my idea, which I'll respond to properly later today. I'm going to call the mechanism I describe bus request reset.

It's good that you've written code to discover MEMPTR/WZ and I'm looking at it now. JP (IX) and JP (IY) are also available as jumps that don't affect WZ.

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

Re: Z80 Protocol Decoder

Post by hoglet » Tue Aug 14, 2018 1:56 pm

And here's a greatly improved version that only has one loop, and uses IX as the counter.

It works by decrementing MEMPTR until bit 13 is seen to change state, which is much simpler. This works out bits 12..0, and we can just OR-in bit 13 at the end. So it ends up being faster as well.

Code: Select all

   10 code%=&E000
   20 FOR I%=0 TO 3 STEP 3
   30 P%=code%
   40 [OPT I%
   50 .test
   60 DI
   70 LD A,(&0000)
   80 \ work out the value of MEMPTR without disturbing it
   90 LD IX,&FFFF
  100 \ copy bit 13 of MEMPTR INTO E
  110 BIT 0,(HL)
  120 PUSH AF
  130 POP DE
  140 LD A,E
  150 AND &20
  160 LD E,A
  170 \ loop decementing MEMPTR until bit 13 flips
  180 .loop
  190 INC IX
  200 CPD
  210 BIT 0,(HL)
  220 PUSH AF
  230 POP BC
  240 LD A,C
  250 XOR E
  260 AND &20
  270 LD HL,loop
  280 ADD A,L
  290 LD L,A
  300 JP (HL)
  310 \ add NOPs so to align next block to loop + &20
  320 NOP
  330 NOP
  340 NOP
  350 NOP
  360 NOP
  370 NOP
  380 NOP
  390 NOP
  400 NOP
  410 NOP
  420 NOP
  430 NOP
  440 NOP
  450 NOP
  460 \ OR-in bit 13 of MEMPTR from E
  470 PUSH IX
  480 POP HL
  490 LD A,H
  500 OR E
  510 LD H,A
  520 EI
  530 \ result is now in HL bits 13..0
  540 RET
  550 ]
  560 NEXT
  570 PRINT "Press a key to run test"
  580 Z=GET
  590 FOR X%=1 TO &10000 STEP &123
  600 test?2=(X%-1) MOD 256
  610 test?3=(X%-1) DIV 256
  620 Y%=USR(test) DIV &10000
  630 PRINT ~X%,~Y%
  640 IF Y%<>(X% AND &3FFF) PRINT "FAIL":END
  650 NEXT
Dave
Last edited by hoglet on Tue Aug 14, 2018 2:12 pm, edited 2 times in total.

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

Re: Z80 Protocol Decoder

Post by TonyB » Tue Aug 14, 2018 2:16 pm

hoglet wrote:
Tue Aug 14, 2018 1:56 pm
And here's a greatly improved version that only has one loop, and uses IX as the counter.

It works by decrementing MEMPTR until bit 13 is seen to change state, which is much simpler. This works out bits 12..0, and we can just OR-in bit 13 at the end. So it ends up being faster as well.

Code: Select all

   10 code%=&E000
   20 FOR I%=0 TO 3 STEP 3
   30 P%=code%
   40 [OPT I%
   50 .test
   60 DI
   70 LD A,(&0000)
   80 \ work out the value of MEMPTR without disturbing it
   90 LD IX,&FFFF
  100 \ copy bit 13 of MEMPTR INTO E
  110 BIT 0,(HL)
  120 PUSH AF
  130 POP DE
  140 LD A,E
  150 AND &20
  160 LD E,A
  170 \ loop decementing MEMPTR until bit 13 flips
  180 .loop
  190 INC IX
  200 CPD
  210 BIT 0,(HL)
  220 PUSH AF
  230 POP BC
  240 LD A,C
  250 XOR E
  260 AND &20
  270 LD HL,loop
  280 ADD A,L
  290 LD L,A
  300 JP (HL)
  310 \ add NOPs so to align next block to loop + &20
  320 NOP
  330 NOP
  340 NOP
  350 NOP
  360 NOP
  370 NOP
  380 NOP
  390 NOP
  400 NOP
  410 NOP
  420 NOP
  430 NOP
  440 NOP
  450 NOP
  460 \ OR-in bit 13 of MEMPTR from E
  470 PUSH IX
  480 POP HL
  490 LD A,H
  500 OR E
  510 LD H,A
  520 EI
  530 \ result is now in HL bits 13..0
  540 RET
  550 ]
  560 NEXT
  570 PRINT "Press a key to run test"
  580 Z=GET
  590 FOR X%=1 TO &10000 STEP &123
  600 test?2=(X%-1) MOD 256
  610 test?3=(X%-1) DIV 256
  620 Y%=USR(test) DIV &10000
  630 PRINT ~X%,~Y%
  640 IF Y%<>(X% AND &3FFF) PRINT "FAIL":END
  650 NEXT
Dave
A minor point: LD HL,loop is needed only once before the loop as you're adding 0 to L until bit 13 flips.

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

Re: Z80 Protocol Decoder

Post by TonyB » Tue Aug 14, 2018 2:26 pm

TonyB wrote:
Tue Aug 14, 2018 2:16 pm
hoglet wrote:
Tue Aug 14, 2018 1:56 pm
And here's a greatly improved version that only has one loop, and uses IX as the counter.

It works by decrementing MEMPTR until bit 13 is seen to change state, which is much simpler. This works out bits 12..0, and we can just OR-in bit 13 at the end. So it ends up being faster as well.

Code: Select all

   10 code%=&E000
   20 FOR I%=0 TO 3 STEP 3
   30 P%=code%
   40 [OPT I%
   50 .test
   60 DI
   70 LD A,(&0000)
   80 \ work out the value of MEMPTR without disturbing it
   90 LD IX,&FFFF
  100 \ copy bit 13 of MEMPTR INTO E
  110 BIT 0,(HL)
  120 PUSH AF
  130 POP DE
  140 LD A,E
  150 AND &20
  160 LD E,A
  170 \ loop decementing MEMPTR until bit 13 flips
  180 .loop
  190 INC IX
  200 CPD
  210 BIT 0,(HL)
  220 PUSH AF
  230 POP BC
  240 LD A,C
  250 XOR E
  260 AND &20
  270 LD HL,loop
  280 ADD A,L
  290 LD L,A
  300 JP (HL)
  310 \ add NOPs so to align next block to loop + &20
  320 NOP
  330 NOP
  340 NOP
  350 NOP
  360 NOP
  370 NOP
  380 NOP
  390 NOP
  400 NOP
  410 NOP
  420 NOP
  430 NOP
  440 NOP
  450 NOP
  460 \ OR-in bit 13 of MEMPTR from E
  470 PUSH IX
  480 POP HL
  490 LD A,H
  500 OR E
  510 LD H,A
  520 EI
  530 \ result is now in HL bits 13..0
  540 RET
  550 ]
  560 NEXT
  570 PRINT "Press a key to run test"
  580 Z=GET
  590 FOR X%=1 TO &10000 STEP &123
  600 test?2=(X%-1) MOD 256
  610 test?3=(X%-1) DIV 256
  620 Y%=USR(test) DIV &10000
  630 PRINT ~X%,~Y%
  640 IF Y%<>(X% AND &3FFF) PRINT "FAIL":END
  650 NEXT
Dave
A minor point: LD HL,loop is needed only once before the loop as you're adding 0 to L until bit 13 flips.
Change LD HL,loop to RRA and insert LD HL,loop before .loop and all the NOPs can be deleted!

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

Re: Z80 Protocol Decoder

Post by hoglet » Tue Aug 14, 2018 2:49 pm

TonyB wrote:
Tue Aug 14, 2018 2:16 pm
A minor point: LD HL,loop is needed only once before the loop as you're adding 0 to L until bit 13 flips.
TonyB wrote:
Tue Aug 14, 2018 2:26 pm
Change LD HL,loop to RRA and insert LD HL,loop before .loop and all the NOPs can be deleted!
I don't think that is going to work, because CPD decrements HL.

Edit: but it might work if I used JP (IY).... I'll try this

Edit2: or we could correct HL after the CPD

Dave
Last edited by hoglet on Tue Aug 14, 2018 2:50 pm, edited 3 times in total.

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

Re: Z80 Protocol Decoder

Post by TonyB » Tue Aug 14, 2018 2:58 pm

hoglet wrote:
Tue Aug 14, 2018 2:49 pm
TonyB wrote:
Tue Aug 14, 2018 2:16 pm
A minor point: LD HL,loop is needed only once before the loop as you're adding 0 to L until bit 13 flips.
TonyB wrote:
Tue Aug 14, 2018 2:26 pm
Change LD HL,loop to RRA and insert LD HL,loop before .loop and all the NOPs can be deleted!
I don't think that is going to work, because CPD decrements HL.

Edit: but it might work if I used JP (IY).... I'll try this

Edit2: or we could correct HL after the CPD

Dave
My mistake, apologies.

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

Re: Z80 Protocol Decoder

Post by TonyB » Tue Aug 14, 2018 3:05 pm

Try again:

Code: Select all

  0010                          .RADIX 16
                                ;
  0100                          test:
  0100    F3                    	DI
  0101    3A 0000               	LD A,(0000)
                                ;
                                ; work out the value of MEMPTR without disturbing it
                                ;
  0104    DD 21 FFFF            	LD IX,0FFFF
                                ;
                                ; copy bit 13 of MEMPTR into E
                                ;
  0108    CB 46                 	BIT 0,(HL)
  010A    F5                    	PUSH AF
  010B    D1                    	POP DE
  010C    16 20                 	LD D,20
  010E    7B                    	LD A,E
  010F    A2                    	AND D
  0110    5F                    	LD E,A
                                ;
                                ; LOOP decrementing MEMPTR until bit 13 flips
                                ;
  0111    21 0114               	LD HL,LOOP
  0114                          LOOP:
  0114    DD 23                 	INC IX
  0116    ED A9                 	CPD
  0118    23                    	INC HL
  0119    CB 46                 	BIT 0,(HL)
  011B    F5                    	PUSH AF
  011C    C1                    	POP BC
  011D    79                    	LD A,C
  011E    AB                    	XOR E
  011F    A2                    	AND D
  0120    1F                    	RRA
  0121    85                    	ADD A,L
  0122    6F                    	LD L,A
  0123    E9                    	JP (HL)
                                ;
                                ; OR-in bit 13 of MEMPTR from E
                                ;
  0124    DD E5                 	PUSH IX
  0126    E1                    	POP HL
  0127    7C                    	LD A,H
  0128    B3                    	OR E
  0129    67                    	LD H,A
                                ;
                                ; result is now in HL bits 13..0
                                ;
  012A    C9                    	RET

Changed, then changed back, as right first time, I think.
Last edited by TonyB on Tue Aug 14, 2018 3:11 pm, edited 3 times in total.

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

Re: Z80 Protocol Decoder

Post by hoglet » Tue Aug 14, 2018 3:25 pm

TonyB wrote:
Tue Aug 14, 2018 3:05 pm
Changed, then changed back, as right first time, I think.
That works, nice optimization!

Code: Select all

   10 code%=&E000
   20 FOR I%=0 TO 3 STEP 3
   30 P%=code%
   40 [OPT I%
   50 .test
   60 DI
   70 LD A,(&0000)
   80 \ work out the value of MEMPTR without disturbing it
   90 LD IX,&FFFF
  100 \ copy bit 13 of MEMPTR INTO E
  110 BIT 0,(HL)
  120 PUSH AF
  130 POP DE
  140 LD D,&20
  150 LD A,E
  160 AND D
  170 LD E,A
  180 LD HL,loop
  190 \ loop decementing MEMPTR until bit 13 flips
  200 .loop
  210 INC IX
  220 CPD
  230 INC HL
  240 BIT 0,(HL)
  250 PUSH AF
  260 POP BC
  270 LD A,C
  280 XOR E
  290 AND D
  300 RRA
  310 ADD A,L
  320 LD L,A
  330 JP (HL)
  340 \ OR-in bit 13 of MEMPTR from E
  350 PUSH IX
  360 POP HL
  370 LD A,H
  380 OR E
  390 LD H,A
  400 EI
  410 \ result is now in HL bits 13..0
  420 RET
  430 ]
  440 NEXT
  450 PRINT "Press a key to run test"
  460 Z=GET
  470 TIME=0
  480 FOR X%=1 TO &10000 STEP &123
  490 test?2=(X%-1) MOD 256
  500 test?3=(X%-1) DIV 256
  510 Y%=USR(test) DIV &10000
  520 PRINT ~X%,~Y%
  530 IF Y%<>(X% AND &3FFF) PRINT "FAIL":END
  540 NEXT
  550 PRINT TIME
Dave

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

Re: Z80 Protocol Decoder

Post by TonyB » Tue Aug 14, 2018 3:46 pm

hoglet wrote:
Tue Aug 14, 2018 7:27 am
Hi Tony,

Yes, indeed an interesting idea and thought-provoking idea.

Am I right in thinking the main advantage over any existing software approach is the ability to gain some insights into the operation of an instruction machine cycle by machine cycle?

... I'm pretty happy that the Z80 Decoder is accurately tracking all the Z80 registers and flags. If there is a more targeted WZ test suite, that would be worth trying. Does such a thing exist?

Your device does sound very interesting though. Are there specific questions you would try to answer with it?

Dave
Dave,

Thanks again for the positive comments. My bus request reset hardware would give a greater insight into the inner workings of the Z80 than software only and I think the greatest possible short of more reverse engineering from die photos done thus far.

The main thing I hope it will tell us is WZ at the end of each M cycle but we would see other registers change. I believe that the AF pair are loaded into the ALU at the start of each instruction. Are they written back to the register file only once at the end of the instruction or multiple times? My device should tell us that as well by looking at 16-bit adds, for example.

There is no point using it for single M cycle instructions or double ones with a prefix, which eliminates hundreds, nor setting the reset point to the last M cycle except for block instructions. The device should work with pretty much any Z80 system, even the Spectrum if ROM modified or switched out and replaced with RAM. Assuming low memory is RAM, the easiest thing to do is patch the first two bytes with either JP (IX) or JP (IY) to get back to the test code in higher memory without destroying WZ. As IX and IY work identically, only one is required for instruction testing.

As instructions are frozen then a reset occurs immediately afterwards, my device would be a much quicker way of testing the block instructions than waiting for an interrupt to change the flags. Also, calls, jumps, restarts and the IM 2 interrupt acknowledge cycle could be studied without the calls or jumps ever taking place, as reset occurs first. Having said that, all the information is known about these already, probably.

All the pins on the GAL are used up but the logic is quite simple. If a small CPLD were used instead with the data bus added, it could provide the interrupt vector and IM 0 opcode, disabling the IC that outputs the former on the Acorn Co Pro. However this is overkill, to start with at least.

Have you tested CPxR, INxR and OTxR during interrupts? I don't see why the repeat logic would differ from LDxR.
Last edited by TonyB on Tue Aug 14, 2018 4:02 pm, edited 2 times in total.

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

Re: Z80 Protocol Decoder

Post by TonyB » Tue Aug 14, 2018 3:57 pm

Something that puzzles me a little bit is how the Russian MEMPTR/WZ investigators know WZ when BC <> 1 during LDxR, as it must be overwritten during IM 1 and 2 interrupts. I doubt they used any hardware, but perhaps they added pull-up/pull-down resistors on the data bus to set the IM 0 opcode to E9H for JP (HL). Or does the NMI preserve WZ? I'm not suggesting their information is wrong.
Last edited by TonyB on Tue Aug 14, 2018 4:25 pm, edited 2 times in total.

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

Re: Z80 Protocol Decoder

Post by hoglet » Tue Aug 14, 2018 4:46 pm

TonyB wrote:
Tue Aug 14, 2018 3:46 pm
Have you tested CPxR, INxR and OTxR during interrupts? I don't see why the repeat logic would differ from LDxR.
No I haven't, so I've just now tried INIR.

You are right, when interrupted it seems to be following the same pattern as LDIR.

My decoder is currently wrong on this case, so I'll fix and re-test.

I'll try the others later.

Dave

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

Re: Z80 Protocol Decoder

Post by hoglet » Tue Aug 14, 2018 5:54 pm

TonyB wrote:
Tue Aug 14, 2018 3:57 pm
Something that puzzles me a little bit is how the Russian MEMPTR/WZ investigators know WZ when BC <> 1 during LDxR, as it must be overwritten during IM 1 and 2 interrupts. I doubt they used any hardware, but perhaps they added pull-up/pull-down resistors on the data bus to set the IM 0 opcode to E9H for JP (HL). Or does the NMI preserve WZ? I'm not suggesting their information is wrong.
The reference I've been looking at says the following:

Code: Select all

LDIR/LDDR
	when BC == 1: MEMPTR is not changed
	when BC <> 1: MEMPTR = PC + 1, where PC = instruction address
I don't thing they are saying anything about it's value if LDIR is interrupted, i.e. they are referring to BC on entry and MEMPTR on normal completion.

On a different subject, I've updated my decoder to correctly set F5/F3 in INIR and OTIR now. But when interrupted I'm seeing errors flagged on some of the other flags.

Here's an example, where both the H and PV flags end up incorrect.

Code: Select all

M1  FETCH ed  4/ 0
M1  FETCH b3  5/ 0
M2  MEMRD bb  4/ 0: Rd=BB
M3   IOWR bb  8/ 0: Wr=BB

8000 : ED B3           : OTIR                 : A=06 F=   H VNC BC=4302 DE=C000 HL=D0BC IX=3900 IY=7FDE SP=EFD6

M1  FETCH ed  4/ 0
M1  FETCH b3  5/ 0
M2  MEMRD bc  4/ 0: Rd=BC
M3   IOWR bc 13/ 3: Wr=BC

8000 : ED B3           : OTIR                 : A=06 F=   H  NC BC=4202 DE=C000 HL=D0BD IX=3900 IY=7FDE SP=EFD6

M4 INTACK fe  6/ 0
M5  MEMWR 80  3/ 0
M6  MEMWR 00  2/ 0: Wr=8000
M7  MEMRD 14  3/ 0
M8  MEMRD 80  3/ 0: Rd=8014

8000 :                 : INT                  : A=06 F=   H  NC BC=4202 DE=C000 HL=D0BD IX=3900 IY=7FDE SP=EFD4

M1  FETCH e5  6/ 0
M2  MEMWR d0  3/ 0
M3  MEMWR bd  2/ 0: Wr=D0BD

8014 : E5              : PUSH HL              : A=06 F=   H  NC BC=4202 DE=C000 HL=D0BD IX=3900 IY=7FDE SP=EFD2

M1  FETCH f5  6/ 0
M2  MEMWR 06  3/ 0
M3  MEMWR 07  2/ 0: Wr=0607

8015 : F5              : PUSH AF              : A=06 F=     VNC BC=4202 DE=C000 HL=D0BD IX=3900 IY=7FDE SP=EFD0 : fail
My reference for the C, H and V flags was:
http://www.z80.info/zip/z80-documented.pdf

It suggests the C and H should end up identical, but that seems not to be the case, unless I'm getting data sampling errors.

I'll dig into this a bit more tomorrow.

Dave

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

Re: Z80 Protocol Decoder

Post by TonyB » Tue Aug 14, 2018 7:42 pm

hoglet wrote:
Tue Aug 14, 2018 5:54 pm
TonyB wrote:
Tue Aug 14, 2018 3:57 pm
Something that puzzles me a little bit is how the Russian MEMPTR/WZ investigators know WZ when BC <> 1 during LDxR, as it must be overwritten during IM 1 and 2 interrupts. I doubt they used any hardware, but perhaps they added pull-up/pull-down resistors on the data bus to set the IM 0 opcode to E9H for JP (HL). Or does the NMI preserve WZ? I'm not suggesting their information is wrong.
The reference I've been looking at says the following:

Code: Select all

LDIR/LDDR
	when BC == 1: MEMPTR is not changed
	when BC <> 1: MEMPTR = PC + 1, where PC = instruction address
I don't thing they are saying anything about it's value if LDIR is interrupted, i.e. they are referring to BC on entry and MEMPTR on normal completion.
Thanks, my brain has been in complicated mode and I couldn't see the simple!
hoglet wrote:
Tue Aug 14, 2018 5:54 pm
On a different subject, I've updated my decoder to correctly set F5/F3 in INIR and OTIR now. But when interrupted I'm seeing errors flagged on some of the other flags.

Here's an example, where both the H and PV flags end up incorrect.

Code: Select all

M1  FETCH ed  4/ 0
M1  FETCH b3  5/ 0
M2  MEMRD bb  4/ 0: Rd=BB
M3   IOWR bb  8/ 0: Wr=BB

8000 : ED B3           : OTIR                 : A=06 F=   H VNC BC=4302 DE=C000 HL=D0BC IX=3900 IY=7FDE SP=EFD6

M1  FETCH ed  4/ 0
M1  FETCH b3  5/ 0
M2  MEMRD bc  4/ 0: Rd=BC
M3   IOWR bc 13/ 3: Wr=BC

8000 : ED B3           : OTIR                 : A=06 F=   H  NC BC=4202 DE=C000 HL=D0BD IX=3900 IY=7FDE SP=EFD6

M4 INTACK fe  6/ 0
M5  MEMWR 80  3/ 0
M6  MEMWR 00  2/ 0: Wr=8000
M7  MEMRD 14  3/ 0
M8  MEMRD 80  3/ 0: Rd=8014

8000 :                 : INT                  : A=06 F=   H  NC BC=4202 DE=C000 HL=D0BD IX=3900 IY=7FDE SP=EFD4

M1  FETCH e5  6/ 0
M2  MEMWR d0  3/ 0
M3  MEMWR bd  2/ 0: Wr=D0BD

8014 : E5              : PUSH HL              : A=06 F=   H  NC BC=4202 DE=C000 HL=D0BD IX=3900 IY=7FDE SP=EFD2

M1  FETCH f5  6/ 0
M2  MEMWR 06  3/ 0
M3  MEMWR 07  2/ 0: Wr=0607

8015 : F5              : PUSH AF              : A=06 F=     VNC BC=4202 DE=C000 HL=D0BD IX=3900 IY=7FDE SP=EFD0 : fail
My reference for the C, H and V flags was:
http://www.z80.info/zip/z80-documented.pdf

It suggests the C and H should end up identical, but that seems not to be the case, unless I'm getting data sampling errors.
Maybe I'm too simple-minded now but the above log suggests that the flags changed after PUSH AF and before that H = C as expected.

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

Re: Z80 Protocol Decoder

Post by hoglet » Tue Aug 14, 2018 7:48 pm

TonyB wrote:
Tue Aug 14, 2018 7:42 pm
Maybe I'm too simple-minded now but the above log suggests that the flags changed after PUSH AF and before that H = C as expected.
Before the PUSH AF, the flags are what's being predicted by the emulation.

After the PUSH AF, the value that is pushed to the stack represents "reality"

At the point, the emulation corrects itself to match, and sets a flag to indicate an inconsistency was detected,

So (barring any kind of sampling error), the flags after the PUSH AF has been observed represents the true state of the Z80 at that point.

Does that help?

Dave

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

Re: Z80 Protocol Decoder

Post by TonyB » Tue Aug 14, 2018 7:58 pm

hoglet wrote:
Tue Aug 14, 2018 7:48 pm
TonyB wrote:
Tue Aug 14, 2018 7:42 pm
Maybe I'm too simple-minded now but the above log suggests that the flags changed after PUSH AF and before that H = C as expected.
Before the PUSH AF, the flags are what's being predicted by the emulation.

After the PUSH AF, the value that is pushed to the stack represents "reality"

At the point, the emulation corrects itself to match, and sets a flag to indicate an inconsistency was detected,

So (barring any kind of sampling error), the flags after the PUSH AF has been observed represents the true state of the Z80 at that point.
In which case you have found more new flag behaviour.

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

Re: Z80 Protocol Decoder

Post by TonyB » Tue Aug 14, 2018 8:32 pm

The flag info in "The Undocumented Z80 Documented" for the block repeat instructions only applies when the counter = 1.
Last edited by TonyB on Tue Aug 14, 2018 10:40 pm, edited 2 times in total.

Post Reply