Does all of this make sense?
This is the flip flop circuit I plan to use to allow Z80 IN/OUT/DMA with an AVR.
Z80 executes an OUT to 0x80-0x8F:
"0111" A7/A6/A5/A4 along with IORQ# asserted and FFCLEAR# deasserted trigger the flip flop through PRE#.
The flip flop output goes to a logic level N mosfet to assert WAIT# causing the Z80 to wait.
The AVR will notice FFSTATE# asserted on the flip flop and knows it is being addressed.
The AVR evaluates RD# or WR# to determine IN or OUT.
IN instruction:
The AVR grabs A8-A15, A0-A3 (we already know A4-A7) and determines what command the Z80 is trying to input.
The AVR sets data port to output and provides the data on D0-D7.
The AVR asserts BUSREQ# and then asserts FFCLEAR#.
The Z80 will be released from the wait, capture the data IN, and hold at BUSREQ# by asserting BUSACK#.
The AVR waits for BUSACK# assertion, then sets data port back to input.
If command requires DMA, the AVR can do it here.
The AVR deasserts FFCLEAR# (IORQ# is released now and it won't retrigger), then deasserts BUSREQ#.
OUT (with DMA):
The AVR grabs A8-A15, A0-A3 (we already know A4-A7) and determines what command the Z80 is trying to input.
The AVR grabs the data on D0-D7.
The AVR asserts BUSREQ# and then asserts FFCLEAR#.
The Z80 will be released from the wait, and hold at BUSREQ# by asserting BUSACK#.
The AVR waits for BUSACK# assertion.
The AVR can do the DMA here.
The AVR deasserts FFCLEAR# (IORQ# is released now and it won't retrigger), then deasserts BUSREQ#.
OUT (without DMA - if this works):
The AVR grabs A8-A15, A0-A3 (we already know A4-A7) and determines what command the Z80 is trying to input.
The AVR grabs the data on D0-D7.
The AVR asserts FFCLEAR#.
The Z80 will be released from the wait.
The AVR quickly waits for IORQ# to be deasserted and then deasserts FFCLEAR# before any other possible IN/OUT instruction can execute.