I had a go at creating a better "SPI master" with a programmable auto-shift function after a read. It is using just over 40 macrocells so far.
First operation is a write to address 1 to write to the configuration register setting auto-shift (d7) and asserting a built-in slave select pin (d2).
Then I do a read from address 1 just to test the contents of the config register.
Next is a write to address 0 with a value of 0xED which causes that value to be shifted out once CS/ is deasserted. The value 0xB7 is shifted in at the same time.
Then I do a read of address 0 to retrieve the value that was shifted in, after which the auto-shift occurs to shift in another byte, 0xE7.
Then I write again to the config register to deassert the SS and disable auto-shift.
And finally a read from address 0 to retrieve the final value that was shifted in. And since auto-shift was disabled you can see that nothing happens afterwards.
Quite pleased with that. Yes it was written in CUPL. :-)
I did also implement CPOL, and Ive been scratching my head about how I could implement CPHA.
There is probably room for one or two more SS signals, and perhaps also an ability to tri-state MOSI when no SS is asserted.
Im also sort of inspired by Bills CPLD, perhaps using a separate clock for the shifter, enabling higher speed shifting independent of the CPU clock which is used for the internal state machine so that it is synchronous with the CPU, but this wouldn't be strictly necessary if the external clock was at least as fast as the CPU clock, phasing issues aside.