; Z80 register bus on PIO1. ; ; GP0 /OE, GP1 DIR, GP2..9 D0..D7, GP10 /IOREQ, GP11 /RD, ; GP12 CS (A7), GP13..14 A0..A1, GP15 CLK, GP16 /WAIT. ; ; side-set values for GP1:GP0: ; 0 = B->A enabled, 1 = B->A disabled ; 2 = A->B enabled, 3 = A->B disabled .program z80_bus .side_set 2 opt .wrap_target wait 0 gpio 10 nop [1] ; allow synchronized bus signals to settle mov isr, null in pins, 15 ; snapshot GP0..GP14 ; Decode /RD (bit 11) and CS (bit 12), preserving ISR for core 1. mov osr, isr out null, 11 out x, 1 ; X = /RD out y, 1 ; Y = CS jmp !y cycle_done jmp !x read_cycle write_cycle: push block jmp cycle_done read_cycle: set pins, 0 side 1 ; assert /WAIT, disable transceiver push block ; send address request to core 1 pull block side 1 ; wait for response byte ; Prepare data and direction while the transceiver remains disabled. mov x, osr side 1 mov osr, ~null side 3 ; select A->B out pindirs, 8 side 3 ; GP2..GP9 outputs mov osr, x side 3 out pins, 8 side 3 ; put response on A-side pins ; Keep /WAIT asserted through a real falling Z80 clock edge. PIO observes ; the edge through its synchronizer and releases /WAIT just afterwards, ; guaranteeing that the Z80 sampled it low and inserted a wait state. wait 1 gpio 15 side 3 wait 0 gpio 15 side 3 set pins, 1 side 2 ; enable A->B and release /WAIT wait 1 gpio 11 side 2 ; wait for /RD to deassert nop side 3 ; disable before changing direction mov osr, null side 3 out pindirs, 8 side 3 ; GP2..GP9 inputs nop side 1 ; select B->A while disabled nop side 0 ; enable B->A for write reception cycle_done: wait 1 gpio 10 .wrap