60 lines
1.9 KiB
Plaintext
60 lines
1.9 KiB
Plaintext
; 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
|