; t911veryfast.pio -- for the TFR/901 -- strick
; E = 1 ; pin 29
; Q = 2 ; pin 30
; RW pin 31
; Phase1 : 0 : neither
; Phase2 : 2 : just Q
; Phase3 : 3 : both
; Phase4 : 1 : just E

.program t911veryfast
.side_set 2
    jmp Reset       side 0  ; make sure D[0:7] are inputs

.wrap_target
Loop:
    pull block      side 0  ; value ignored; just for synchronization
    nop         [6] side 0  ; 5ok 4bad ; first phase = side 0

    nop         [6] side 2  ; 5ok 4bad
    in pins,32      side 2

    push            side 3  ; third phase = side 3
    jmp pin, Read   side 3

Write:
    nop        [7]  side 3  ; third phase = side 3 ; z8 -1 z9 -2

    nop        [7]  side 1  ; fourth phase = side 1
    in pins, 32     side 1
    push            side 1

    jmp Loop        side 0  ;

Read:
    mov osr, ~null   side 3
    out pindirs, 8   side 3
    pull block      side 3
    out pins,8      side 3

    in pins, 32     side 3 ; LATE PINS
    push            side 1 ; LATE PINS

    nop             side 1
    nop     [7]     side 1  ; 6ok 5bad ; fourth phase = side 1

Reset:
    mov osr, null         side 0
    out pindirs, 8        side 0
.wrap

% c-sdk {
void t911veryfast_program_init(PIO pio, uint sm, uint offset) {

   constexpr uint CLOCK_DIVISOR = 1;

   //  pico-examples/pio/hub75/hub75.pio shows order of inits.
   pio_sm_set_consecutive_pindirs(pio, sm, 0, 8, false/*in*/);
   for (uint i = 0; i < 8; i++) {
       pio_gpio_init(pio, i);
   }
   pio_sm_set_consecutive_pindirs(pio, sm, 0, 8, false/*in*/);
   pio_gpio_init(pio, 29);
   pio_gpio_init(pio, 30);
   pio_sm_set_consecutive_pindirs(pio, sm, 29, 2, true/*out*/);
   pio_gpio_init(pio, 31);
   pio_sm_set_consecutive_pindirs(pio, sm, 31, 1, false/*in*/);

   pio_sm_config cf = t911veryfast_program_get_default_config(offset);
   sm_config_set_jmp_pin(&cf, 31);  // R/W
   sm_config_set_in_pins(&cf, 0);   // D[0:7]
   sm_config_set_out_pins(&cf, 0, 8);   // D[0:7]
   sm_config_set_sideset(&cf, 2, false, false);  // E & Q
   sm_config_set_sideset_pins(&cf, 29);  // E & Q
   sm_config_set_clkdiv(&cf, CLOCK_DIVISOR);

   // IN: Shift from left, do autopush
   const bool IN_SHIFT_RIGHT = true;
   const bool AUTOPUSH = false; // true;
   const uint PUSH_THRESHOLD = 32;
   sm_config_set_in_shift(&cf, IN_SHIFT_RIGHT, AUTOPUSH, PUSH_THRESHOLD);

   // OUT: Shift to right, don't autopull
   const bool OUT_SHIFT_RIGHT = true;
   const bool AUTOPULL = false;
   const uint PULL_THRESHOLD = 8;
   sm_config_set_out_shift(&cf, OUT_SHIFT_RIGHT, AUTOPULL, PULL_THRESHOLD);

   pio_sm_init(pio, sm, offset, &cf);
   pio_sm_exec(pio, sm, offset);
   pio_sm_set_enabled(pio, sm, true);
}
%}
// END
