I am attempting to make a retro computer using a z80 and ideally would like to give it the ability to boot from an SD card. I am 100% set on using a z80 and do not want to use a microcontroller with an internal SPI hardware interface. I want to understand both the hardware and software aspects of a computer, so arduinos and microcontrollers are off the table as the hardware side is completed before you even purchase it. Anyways, my main question is would it be possible to combine a shift register, some decoding logic, and software to read from an SD card via SPI mode? I have searched the internet for hours and read several articles and cant seem to find a tutorial. I understand SPI protocol, however, there is a lack of information regarding the hardware side because microcontrollers tend to have all the hardware built in. I planned on connecting the SOMI of the SD card to the serial input pin of a shift register, the SIMO of the SD card to the serial out pin of the shift register, and then connecting a few data pins to some flip flops with some decoding logic inbetween, so that if I output to a specific port, it will toggle the flip flops. The flip flops would serve as the clock and chip enable lines to the SD card. I would also connect a pin of the z80 to the latch pin of the shift register (again with decoding logic inbetween) so that if I output to a specific port it will latch the data of the shift register. Im unconcerned with speed/efficiency, as long as I can accurately read data from the SD card. Also, would I connect the shift register clock input to the same clock as I connect the SD card to? Any advice on how to implement this would be appreciated, thanks!
Asked
Active
Viewed 2,516 times
5
-
hmm, **Z80 IN z,(C)** op-codes put B register on the bus (as the high address bits) maybe that could be used to streamline the code – Jasen Jul 11 '22 at 05:19
1 Answers
2
You really could just bit bang SPI on regular IO's. All you need is an edge interrupt for the clock signal and a level interrupt for the chip select. Everything else can be done in software. To send, hold the chip select low, and clock out bits on MOSI at the desired rate. To receive, handle chip select going low by sampling bits off MISO on the desired edge on the clock line. Stick everything in a buffer and process the buffer when the chip select line goes back high.

Drunken Code Monkey
- 1,796
- 1
- 14
- 18
-
Isn't that what I'm in essence doing with the shift register? The z80 doesn't have serial input pins and cant change the state of individual output pins/create level outputs on its own. Thats why I used flipflops connected to output ports to generate the clock/chip enable signal. And excuse my lack of knowledge, this is a fairly recent hobby of mine, and ive had to teach myself nearly everything ive learned so far and may have misinterpreted/misunderstood some things along the way. – KeatonB Oct 25 '15 at 23:51
-
1Yes, it is, I was simply suggesting that the shift register is not necessary. Of course if your particular micro doesn't have any means of triggering an interrupt from an external signal, using an external shift register will work. But really, any IO can be a serial IO. Most micros have "parallel IO", but nothing stops you from using them serially. – Drunken Code Monkey Oct 26 '15 at 01:39
-
1I should have added that typically you will see an external shifter mostly when it is connected directly to a memory bus, or if you need high speed. Obviously bit banging will be slower, but often speed is no concern in microcontroller projects. The usual goal is to get the microcontroller to do AS LITTLE as possible to save power. – Drunken Code Monkey Oct 26 '15 at 02:27
-
Additional potentially helpful observation: on a Z80, the NMI line is edge triggered and the IRQ line is level triggered. Though I guess you'd probably want to tie NMI to the clock signal and sample chip select along with data in every time it fires. – Tommy Oct 26 '15 at 23:22
-
@Tommy The only problem with that is that you will also sample data when you are trying to send, and when other devices pull chip select low, meaning servicing more interrupt than you need. If you route chip select to IRQ, and clock to NMI, in the IRQ line ISR you set the interrupt vector to NMI when it goes low and reset it when it goes high. Use a separate boolean flag to set send mode, and check it before sampling data to avoid echo. – Drunken Code Monkey Oct 26 '15 at 23:50
-
Well you're always going to end up servicing more interrupts than you need if you tie to NMI thanks to that NM bit; as you're initiating the read (or is that a false assumption?) you can adjust the vector without tying it to an interrupt, costing you a little around the edges but possibly buying simpler IRQ logic. Though if there were no other interrupting devices then it's not worth the effort. – Tommy Oct 27 '15 at 01:49