This probably belongs here rather than the MegaThread:
15 hours ago, BruceMcF said:
Heck, I see that the SD card SPI CS and the serial ROM SPI CS is side by side in a control register in the X8, and there might be one spare pin (if it isn't a pin stranded by lack of logic resources), and I'm like, "hey, that's a job for a 74x138, just send three bits out on pins undecoded, and you get 7 alternative SPI selects."
...
... OOH! WAIT! It might be possible to finesse away the need for a spare pin!
Use the next decoder! A 74x139 dual active low 2>4 decoder ... that's the ticket!
See, if you include a GPIO extender, you can use some of that GPIO for system uses. So you have one decoder, /EN tied to ground so it's always on, tied to the two pins that were original SD and serial flashROM CS's. So %01 SD card, %10 serial flash ROM %11 GPIO extender ... %00, SPI expansion bus. ...
Oh,
sticker price shock ... I looked at Mouser and one of those SPI 28-port port extenders is like $6+ Q1 ... as a rule of thumb, double for built cost and add 20% operating margin, maybe $15 added to the price of the board.
OK, that locks in the 7x139 decoder approach even more.
I believe the following works, but don't have any hardware to test it, so it's all speculative. Also the X8 specifics that it is based on are unofficial sources as well, so they may be incorrect.
As above, don't decode the SD and flash ROM selects internally, just send the state out to the pins, and put those two pins into one half of the 2>4 decoder. The other half is used to filter the SPI serial clock so that the shift register only receives the serial clock when the serial shift register is "enabled". Both decoders have their output enable tied on.
The first decoder outputs are %01 to the SD card CS, $10 to the flash ROM CS, %11 to the serial shift register register clock and to be decoded by the second decoder, %00 goes to the output enable of the serial shift register.
The low enable from %11 goes into the register clock line of the shift register. It also goes to the second decoder as the b1 input, with the SPI SCLK as the b0 input. The serial shift register clock is the %00 output of the second decoder, so that it only goes low when both serial shift register select and SCLK are low. MOSI goes to the serial input of the serial shift register, MISO goes to the carry output of the serial shift register.
So when you write a byte into the serial shift register, those are the 8 CS on the SPI expansion port that are selected when the SPI select code is %00. To disable the expansion port, you write $00 to the serial shift register and then %00 leaves everything at rest. For the 74x596, pull up resisters are on the X8 board, since the register outputs are open collector.
Hats shouldn't stack too high, so the SPI hat board specification is simple. The block pin header has SCLK, MOSI, MISO, +3.3V, and CS0-CS7.
The hat specification is as simple as could be, since "hat" boards really shouldn't stack too high, and there are for practical purposes chip selects to spare.
If there truly is a spare pin, and it is not just stranded by lack of logical resources to put it to use, a common Alert line input to the X8 from the boards can be provided. In the lowest logic resource implementation, it is simply a bit in some register somewhere that must be polled. If more logic is available, a second bit might set whether it triggers an IRQ.
There is no protocol on how to find out which of up to 8 SPI devices sent the alert ... while some SPI devices can send alerts (UARTs, I2C bus masters, RTC alarms, GPIO edge detection, etc.) there is no universal standard for how to poll an SPI device to see if it has sent an alert, so that is necessarily left "up to the specific SPI part interface".
A "top hat" board, without a pass through block header, use chip select 0 optionally up to 3 and ignores chip selects 4-7.
A "pass through" board uses chip selects 4 optionally up to 7, and passes chip selects 0-3 through to its own block pin header, while CS4-CS7 are just NC, pulled high with pull up resisters.
______________________
Notes
When this 74x139 decoder is based on the SCLK from a Mode0 SPI master, IIUC the result is not true Mode0 synchronization, since the rising of the output register clock line acting as CS will be accompanied by an "extra" rising serial clock. According to the datasheet, the correct value will be in the output register, but the serial shift register itself will be one shift ahead. So the "echo" of the old contents received on MISO might be seven of the prior bits, shifted one bit. However, this wouldn't affect the functioning of the SPI expansion port CS lines.
With a Mode3 SPI bus master, which is the "natural" mode for the VIA serial shift registers, IIUC, this may be true Mode3 synchronization.
I always thought an interesting upgrade on the bit banged approach for a C64 SPI bus was to set up one serial shift register to receive the MISO data, which just requires wiring the GPIO used to bit bang the serial clock (d0) with the line that can drive the serial shift register from an external clock. Then the bit banging is only handling select, SCLK and MOSI, so you store to Port A with the clock line at d0 set to zero and INC the register to raise the clock. Then clock phase is entirely in software control. The next quite substantial step up in speed (to 500kbps) is to use both serial shift registers, for MISO and MISO, but without circuitry above my head, that ends up with a Mode3 interface, so it cannot talk to an SD card in SPI mode. A few decades back I was assuming that a 16v8 SPLD could implement a bridge to take a Mode3 master in and generate a Mode0 bus, but that assumption was as far as my early 2000's explorations got, as I was never in a position to get a real C64 while I was in Oz.
But I always thought that the "half bit banged" loop was just about as efficient as serial bit banging can get: "SPISTATUS" has the six CS, which go out on d1-d6, except shifted up one, with the low two bits 0:
LDX #8 : LDY SPISTATUS : - TYA : ASL SPIDATA : ROR : STA USERPA : INC USERPA : DEX : BNE -
... so around 25 clocks per bit, or 40kbps on the C64's User Port. There is no need for a "slow mode" of course, since that is well under the 400kbps ceiling during part of some SD card's initialization (though the dual serial shift register is JUST over this threshold, and would have to take this into account).