Sometimes I worry about myself. I could have just been normal and used an SD card in SPI mode like everyone. But, no, I had to be special and try to use an SD card in SD mode. Unlike every. single. other. person who has ever posted anything about using SD cards.
So this post falls somewhere between a plea for help and a tutorial on how to use an SD card in SD mode.
The first problem I ran into (apart from nobody at all posting anything about SD mode) is that there are a dozen conflicting datasheets over about two decades; none of which contained the whole story. You might expect the SD card association would be the place to start but the Simplified Physical Layer Specification is three hundred pages. And unless you already know what you're looking for it is almost impossible to find anything in it.
For example: When is data on the CMD line read by the card? Is it when the CLK transitions high-to-low or low-to-high? Or something else? It's on page 273 under bus timings. Like. I. just... AaaaghI only found that after a muddy version in a twenty year old SanDisk datasheet that clued me in on what to search for.
Incidentally, the answer is low-to-high. The SD card reads data on the CMD line when the CLK goes low-to-high. And the host must similarly read data on the CMD line (presented by the card) when the CLK goes low-to-high.
Speaking of CMD, below is an SD card pin-out:
With that out the way let the adventure begin with trying to initialise an SD card.
First you have to put a newly powered up card into IDLE mode by sending it cmd0 and then send it cmd8 to ask what voltages it supports. Before you can send cmd0 you you have to set CMD high and tick the CLK 80 times at 100KHz. Or maybe you have to tick the clock 75 times. Or none. I ticked it 8 times and the category 10 SanDisk card I'm using seemed happy.
Again before cmd0 can be sent to put the card in SD mode DAT3 must be set high too. In theory all you DAT lines should be set as high impedance inputs and each should have a 10KΩ+ pull up resistor on. I used pull down resistors (because of course I did) so I had to set DAT3 as a high output because I couldn't rely on the (non-existent) pull-up resistor to do it for me. Still worked fine though. CMD should also have a 10KΩ+ pull up resistor. If DAT3 is set a low output the SD card will switch into SPI mode at this point.
Next we're going to jump straight over how to send commands and take a look at what a successfully sent command looks like on an oscilloscope. A picture really is worth a thousand words.
A SD card command has the following form:It is sent on the CMD line at one bit per CLK tick from the highest bit first, bit 47, until the stop transmission bit, bit 0. The stop transmission bit basically just leaves CMD high so that the next transmission start bit can be detected. With that said it has been suggested that CLK should be ticked 8 times after cmd0 has been sent to allow the card to initialise itself. Is it necessary nowadays? I don't know but I'm afraid to not tick the clock of the idle command now.
The argument bits to cmd0 are ignored but best practice is to send all zeros. It's also worth noting there is a bit of confusion around the internet on what the CRC of an SD card command is (either in SD mode or SPI mode). The SD card command uses a crc7 with the generator polynomial: x7 + x3 + 1. For the five cmd0 zero bytes 0x40 00 00 00 00 that 7 bit crc is calculated to be 0x4a. To bring it to 8 bits the stop transmission bit is appended to the end making the 6 byte for cmd0 0x95. 0x95 is not the CRC 0x4a is.
In the attached oscilloscope screenshot you might have seen that I hold the clock high for some time after I'm done ticking cmd0. That's not intentional, it is an artifact from the Raspberry Pi Pico I'm using to bit-bang out the signal. I suspect it has something to do with the debugger but having it attached or not makes no difference. The Pico pauses occasionally but very consistently.
After the SD card has been placed in idle mode with cmd0 (and there is no response to cmd0 so in SD mode so you just have to hope it worked); then cmd8 must be sent to select the allowed supply voltage. Practically there is only one voltage option so set command bit 16 to a one. Bits 19 to 16 are the voltage arguments but I think it might be best to steer clear of low voltage SD cards for hobby projects.
cmd8 is useful in that it also has a check pattern that will be echoed back in its response. I've used 0xAA but the choice of bits is entirely optional.
Once I'm done banging out the command the CMD line must be set to input as cmd8 expects a response. The line briefly goes to a noise high impedance state from both the Pico (the host) and the SD card. I did eventually swap out my pull-down for pull-up resistors.
Within two clock ticks after completing the command send the SD card has grabbed the CMD line and started driving it high.
A few clock ticks later and the SD cards transmission start bit (a zero) is seen on the CMD line followed by another zero indicating it is the card transmitting. CLK is still being driven by the Pico and is never set to be an input.
The most interesting thing to note here (apart from getting any response at all from the blasted card) is the the check pattern being echoed back. Bit 16 will also be set to indicate the card supports 3.3V. The long clock on the last check bit is, again, the Pico doing some random wait thing.
And that's it for now. The start of a long journey but getting any response at all in SD mode is far from simple. I'm pretty happy with where it is and am going to leave it here for now.
Using an SD card in SD Mode
Using an SD card in SD Mode
Last edited by AndrewP on Sat Aug 20, 2022 7:13 pm, edited 2 times in total.
Re: Using an SD card in SD Mode
You're not the only one. Yes, I could have used SPI mode just like everyone else. But where's the fun in that?
At the moment, I'm bit-banging the interface in software. The VHDL interface is waiting for a better understanding of what it needs to do, freeing up some space in the FPGA, and for me to find sufficient time and strength to do it. That's going to be a long wait.
The specification is a very big document. The information you need is scattered all the way through it. Hit your head against it enough, and you will eventually learn how to find things. But there will always be surprise bits of information in footnotes in chapters you haven't even glanced at. They'll turn out to be important.
My power-up sequence goes:
I haven't implemented block writes yet.
You'll need two CRC routines. I found them fairly straight-forward, following the description in section 4.5. I do them one bit at a time as the bit is sent, rather than trying to work a byte at a time. There are examples in the specification to test with, and I can provide more if you need them.
I can post my code if it would help. It's for my 65020 CPU, which although derived from and compatible with the 6502, is not a 6502. You wouldn't be able to use it directly.
At the moment, I'm bit-banging the interface in software. The VHDL interface is waiting for a better understanding of what it needs to do, freeing up some space in the FPGA, and for me to find sufficient time and strength to do it. That's going to be a long wait.
The specification is a very big document. The information you need is scattered all the way through it. Hit your head against it enough, and you will eventually learn how to find things. But there will always be surprise bits of information in footnotes in chapters you haven't even glanced at. They'll turn out to be important.
My power-up sequence goes:
- CMD0 "GO_IDLE_STATE"
- CMD8 "SEND_IF_COND"
- CMD55 "APP_CMD", ACMD41 "SD_SEND_OP_COND" with argument 40100000 (HCS=1, voltage = 3.3). The R3 response has HCS and the supported voltages set. Repeat until bit 31 of the response is 1.
- CMD2 "ALL_SEND_CID" with argument 00000000. The R2 response has the CID. I ignore it.
- CMD3 "SEND_RELATIVE_ADDR" with argument 00000000. The R6 response contains the RCA and some status that I ignore.
- CMD7 "SELECT/DESELECT_CARD" with argument bits 31-16 = the RCA you were given, 15-0 = 0. The R1b response I ignore.
- CMD17 "READ_SINGLE_BLOCK" with argument = the block address. The R1 response I ignore, but there will also be the block data. Keep toggling the clock, and you'll eventually see a start bit followed by a block of data and a CRC.
I haven't implemented block writes yet.
You'll need two CRC routines. I found them fairly straight-forward, following the description in section 4.5. I do them one bit at a time as the bit is sent, rather than trying to work a byte at a time. There are examples in the specification to test with, and I can provide more if you need them.
I can post my code if it would help. It's for my 65020 CPU, which although derived from and compatible with the 6502, is not a 6502. You wouldn't be able to use it directly.
Re: Using an SD card in SD Mode
reading a bit online, i'm not sure if SD Mode is ok to use for hobbyist.
you need a licence to be allowed to implement an SD Mode interface for a commercial product, or even to get the full documentation on the standard. but DIY projects like these aren't about selling a product (they are about learning and giving hobbyists more things to play with!) so i don't know if a licence is still required to publish this kind of information and potentially fully functional SD compatibile controllers online for free.
overall i can kinda see why no one really bothers with SD-Mode, it seems like a legal headache for open source/public projects.
you need a licence to be allowed to implement an SD Mode interface for a commercial product, or even to get the full documentation on the standard. but DIY projects like these aren't about selling a product (they are about learning and giving hobbyists more things to play with!) so i don't know if a licence is still required to publish this kind of information and potentially fully functional SD compatibile controllers online for free.
overall i can kinda see why no one really bothers with SD-Mode, it seems like a legal headache for open source/public projects.
Re: Using an SD card in SD Mode
There are parts of the specification missing from the freely-downloadable document, but they aren't necessary to implement a hobbyist-level interface. It includes timing specification (rise and fall times, setup and hold, etc), but not voltage thresholds and power consumption. And I think some details of some of the advanced features that I have no intention of using are omitted too.
Curiously, the timing specification for SPI mode is one of the things that's missing.
No reverse-engineering is required - everything you need is in the freely available document. It's not easy to find, because it's a huge document. But it is in there.
"No one" (it's not really no one) uses SD mode because the microcontrollers that people tend to use already have SPI in hardware, and SPI mode is a little easier to implement - the CRCs are optional, to start with. SD mode is more work. That's all it is.
The legal argument strikes me as a red herring. There is no difference in licencing between SD mode and SPI mode. If you need it for the way you're using SD mode, you need it for SPI mode too. If I was selling a product, I would have to do things properly. But I'm not and have no intention to.
Curiously, the timing specification for SPI mode is one of the things that's missing.
No reverse-engineering is required - everything you need is in the freely available document. It's not easy to find, because it's a huge document. But it is in there.
"No one" (it's not really no one) uses SD mode because the microcontrollers that people tend to use already have SPI in hardware, and SPI mode is a little easier to implement - the CRCs are optional, to start with. SD mode is more work. That's all it is.
The legal argument strikes me as a red herring. There is no difference in licencing between SD mode and SPI mode. If you need it for the way you're using SD mode, you need it for SPI mode too. If I was selling a product, I would have to do things properly. But I'm not and have no intention to.
Re: Using an SD card in SD Mode
John West wrote:
There are parts of the specification missing from the freely-downloadable document, but they aren't necessary to implement a hobbyist-level interface. It includes timing specification (rise and fall times, setup and hold, etc), but not voltage thresholds and power consumption. And I think some details of some of the advanced features that I have no intention of using are omitted too.
Curiously, the timing specification for SPI mode is one of the things that's missing.
No reverse-engineering is required - everything you need is in the freely available document. It's not easy to find, because it's a huge document. But it is in there.
Curiously, the timing specification for SPI mode is one of the things that's missing.
No reverse-engineering is required - everything you need is in the freely available document. It's not easy to find, because it's a huge document. But it is in there.
John West wrote:
"No one" (it's not really no one) uses SD mode because the microcontrollers that people tend to use already have SPI in hardware, and SPI mode is a little easier to implement - the CRCs are optional, to start with. SD mode is more work. That's all it is.
John West wrote:
The legal argument strikes me as a red herring. There is no difference in licencing between SD mode and SPI mode. If you need it for the way you're using SD mode, you need it for SPI mode too.
John West wrote:
If I was selling a product, I would have to do things properly. But I'm not and have no intention to.
I think i'm overreacting because i don't know much about legal stuff so i try to steer clear of anything close to being in a legal gray/red zone... sorry about that.
Re: Using an SD card in SD Mode
I can understand your frustration. And I have only used the SD interface in SPI mode… but there is really no «correct» way to get all cards to work. I even used error checksums (which most DIY instructions jumps over). So I settled with one card working. I can’t say it is finished, but at least its able to read files 99% of the time.
Re: Using an SD card in SD Mode
John West wrote:
My power-up sequence goes:
- CMD0 "GO_IDLE_STATE"
- CMD8 "SEND_IF_COND"
- CMD55 "APP_CMD", ACMD41 "SD_SEND_OP_COND" with argument 40100000 (HCS=1, voltage = 3.3). The R3 response has HCS and the supported voltages set. Repeat until bit 31 of the response is 1.
- CMD2 "ALL_SEND_CID" with argument 00000000. The R2 response has the CID. I ignore it.
- CMD3 "SEND_RELATIVE_ADDR" with argument 00000000. The R6 response contains the RCA and some status that I ignore.
- CMD7 "SELECT/DESELECT_CARD" with argument bits 31-16 = the RCA you were given, 15-0 = 0. The R1b response I ignore.
- CMD17 "READ_SINGLE_BLOCK" with argument = the block address. The R1 response I ignore, but there will also be the block data. Keep toggling the clock, and you'll eventually see a start bit followed by a block of data and a CRC.
What I really want to do is read in data as 8 bits at 10MHz. Why? Well in theory (and simulation) I have a DMA transfer that can do 1 byte every 100ns (or 10MB/s) and that seems like a perfect match for an SD card. For a '816 based system with limited memory being able to dump data into memory faster than the CPU can read it opens the door to some interesting tricks. But I'm rambling and none of this exists in the real world.
More practically what I actually have is '816 stress testing board which is an '816 connected directly to 512KB of SRAM. Absolutely nothing else, no address decoding, no nothing. Kinda. There is also a Raspberry Pi Pico on the board that can (slowly) write into memory when it has disabled the '816's bus. The Pico then disconnects itself from the bus, resets the '816 and lets it fly using an LTC6903 to generate PHI2. To check everything went well it disables the '816s bus again and (slowly) reads that memory back in.
Where does SD card reading come into this? Well, I need practice reading an SD Card for the future and I need *something* to put in memory for the '816 to run against. I also need to get the contents of that memory back out onto a (human) usable device. Plugging an SD card into a Windows PC just seems like less pain than trying to do '816 dev on Raspberry Pi 4.
John West wrote:
You'll need two CRC routines. I found them fairly straight-forward, following the description in section 4.5. I do them one bit at a time as the bit is sent, rather than trying to work a byte at a time. There are examples in the specification to test with, and I can provide more if you need them.
I can post my code if it would help. It's for my 65020 CPU, which although derived from and compatible with the 6502, is not a 6502. You wouldn't be able to use it directly.
I can post my code if it would help. It's for my 65020 CPU, which although derived from and compatible with the 6502, is not a 6502. You wouldn't be able to use it directly.
Re: Using an SD card in SD Mode
OK, here it is. The CPU is based on the 6502, but there are some important differences you'll need to know to understand the code.
Memory locations are 16 bits wide. So address 0 contains 16 bits, address 1 contains another 16 bits, and so on. Registers are 32 bits wide. The .w and .l suffixes on instructions indicate that it's operating on 16 or 32 bits of data. 32 bit data in memory is stored in an unusual format in two consecutive locations, but I don't think the details are important here.
There are twelve general purpose registers: A0 to A3, X0 to X3, and Y0 to Y3. LDR and STR are aliases for LDA, LDX, LDY and STA, STX, STY that choose the right instruction based on the register they're given. Similarly, PSH and PUL are aliases for PHA, PHX, PHY and PLA, PLX, PLY. RLB is like ROL, except it doesn't include carry. BRA is an unconditional branch. BRA.l pushes the value of PC before it branches: it's just like JSR, except one location shorter and one cycle faster if the destination is within +/-32K. Shift and rotate instructions have an optional immediate operand, which specifies how many bits to shift.
Registers used in indexed addressing are always 32 bits. I often swap the interpretation of address and index, so instead of being a (small on the 6502) variable offset from a fixed base address, I have a small fixed offset from a variable base. In softSD_checkDat0, rol.w 0, x0 is shifting the new bit into the location that x0 points to. The buffer isn't at 0.
The entry points for this code are softSD_init, softSD_read_block, and softSD_write_block. That last one is still using a 512 location buffer, with 8 bits per location. And it hasn't been tested properly, so might not work at all.
Finally, the board I'm using (a Papilio Duo with the Classic Computing shield) only connects one of the data lines, so I am only using DAT0. Using all four looks like a headache I don't need to have.
Memory locations are 16 bits wide. So address 0 contains 16 bits, address 1 contains another 16 bits, and so on. Registers are 32 bits wide. The .w and .l suffixes on instructions indicate that it's operating on 16 or 32 bits of data. 32 bit data in memory is stored in an unusual format in two consecutive locations, but I don't think the details are important here.
There are twelve general purpose registers: A0 to A3, X0 to X3, and Y0 to Y3. LDR and STR are aliases for LDA, LDX, LDY and STA, STX, STY that choose the right instruction based on the register they're given. Similarly, PSH and PUL are aliases for PHA, PHX, PHY and PLA, PLX, PLY. RLB is like ROL, except it doesn't include carry. BRA is an unconditional branch. BRA.l pushes the value of PC before it branches: it's just like JSR, except one location shorter and one cycle faster if the destination is within +/-32K. Shift and rotate instructions have an optional immediate operand, which specifies how many bits to shift.
Registers used in indexed addressing are always 32 bits. I often swap the interpretation of address and index, so instead of being a (small on the 6502) variable offset from a fixed base address, I have a small fixed offset from a variable base. In softSD_checkDat0, rol.w 0, x0 is shifting the new bit into the location that x0 points to. The buffer isn't at 0.
The entry points for this code are softSD_init, softSD_read_block, and softSD_write_block. That last one is still using a 512 location buffer, with 8 bits per location. And it hasn't been tested properly, so might not work at all.
Finally, the board I'm using (a Papilio Duo with the Classic Computing shield) only connects one of the data lines, so I am only using DAT0. Using all four looks like a headache I don't need to have.
- Attachments
-
- softSD.asm
- (11.73 KiB) Downloaded 122 times
Re: Using an SD card in SD Mode
John West wrote:
OK, here it is. The CPU is based on the 6502, but there are some important differences you'll need to know to understand the code.
Actually your previous comment was a life saver. I was sending ACMD41 with argument 0x40000000 instead of 0x40100000 because I was reading the SPI argument format instead of the SD mode argument format (that bit is reserved and should be 0 in SPI mode). My card was just sitting in an endless busy loop and had me stumped. I suspect ACMD41 with argument 0x00000000 would have worked too but that's an experiment for another time.
So far I've gotten CMD0 to CMD8 to CMD55 + CMD41 (ACMD41) to give me a positive response in SD mode I'll post up some of the timing quirks I ran into in a longer message later. Also worth noting the 74 CLK ticks before CMD0 are required by the specification (page 231) and the 8 ticks after CMD0 are too but I can no longer find where I read that.
Other interesting mistakes I made. CMD55 (the first half of an application specific command) has a response (R1) and testing with an oscilloscope attached rather than a logic analyzer was invaluable as I could see that both the Pico and the Card were driving the CMD line at the same time.
I used 47KΩ pull-up resistors but I should have used something smaller (10KΩ being the smallest suggested). They didn't pull-up fast enough so when I put the Pico CMD pin in input mode it immediately saw a low voltage and thought it was the start transmission bit from the SD card. The work around I'm using is to set the CMD pin as an input (i.e. high impedance) for 4 clocks ticks before I start reading from it and looking for a low. The SD card generally starts driving the CMD line around tick two and starts transmitting around tick 7 after the end of the command transmission.
John West wrote:
Finally, the board I'm using (a Papilio Duo with the Classic Computing shield) only connects one of the data lines, so I am only using DAT0. Using all four looks like a headache I don't need to have.
Last edited by AndrewP on Tue Aug 23, 2022 12:32 pm, edited 1 time in total.
Re: Using an SD card in SD Mode
kakemoms wrote:
I can understand your frustration. And I have only used the SD interface in SPI mode… but there is really no «correct» way to get all cards to work. I even used error checksums (which most DIY instructions jumps over). So I settled with one card working. I can’t say it is finished, but at least its able to read files 99% of the time.
I'm going to probably go the same route where I can get a card working and stick with it; there's just too much wriggle room in the spec. I like the SanDisk 16GB Ultras because they're *really* cheap but run fine in high performance mode.
- Sheep64
- In Memoriam
- Posts: 311
- Joined: 11 Aug 2020
- Location: A magnetic field
Re: Using an SD card in SD Mode
Thank you for doing this essential work. A trend I've noticed in computing is that a storage interface gets deprecated when a linear scan takes more than 48 hours. (Sheep64's 48 Hour Rule.) If I leave a disk formatting on Friday and it isn't finished by Monday then it isn't practical. Likewise for an unindexed search. This limitation applied to ST-506 and IDE. It now applies to 512GB MicroSD accessed at 15Mb/s (or variations thereof).
A quad channel interface gains two iterations of Moore's law. The practical benefit of your work is that neo-retro enthusiasts will be able to buy contemporary consumer storage for an additional four years. Beyond that, I presume that an optical interface is essential.
You might want to investigate Samsung MicroSD. From various firmware updates for cameras, phones and televisions, it is widely known that within the vendor-specific range of control codes, code zero enters debug mode and code one exits debug mode. When a Samsung MicroSD is in debug mode, arbitrary blocks of memory can be read or written. Its ARM microcontroller can also be instructed to execute from arbitrary address. This functionality can be used to temporarily install 6502 simulator. This simulation may have very fast and reliable access to the MicroSD's raw storage - which may be many multiples of the official size. Even without access to storage, this is a cheap, portable and energy efficient way to cluster 6502 simulators - and does not prevent subsequent use as general purpose storage.
There is precedent with 6502 storage. I believe that it is possible to send 256 bytes of executable code to a Commodore floppy drive and this mechanism was occasionally used for copy protection - or, more recently, the obscure demoscene category of Commodore floppy drive music. There is also a strong association between 6502 and ARM. Anyhow, running 6502 on ARM and running 6502 and a storage unit are both accepted practices. However, I don't believe that anyone has combined the practices or run 6502 programs on such small and affordable storage units.
A quad channel interface gains two iterations of Moore's law. The practical benefit of your work is that neo-retro enthusiasts will be able to buy contemporary consumer storage for an additional four years. Beyond that, I presume that an optical interface is essential.
AndrewP on Tue 23 Aug 2022 wrote:
I like the SanDisk 16GB Ultras because they're *really* cheap but run fine in high performance mode.
There is precedent with 6502 storage. I believe that it is possible to send 256 bytes of executable code to a Commodore floppy drive and this mechanism was occasionally used for copy protection - or, more recently, the obscure demoscene category of Commodore floppy drive music. There is also a strong association between 6502 and ARM. Anyhow, running 6502 on ARM and running 6502 and a storage unit are both accepted practices. However, I don't believe that anyone has combined the practices or run 6502 programs on such small and affordable storage units.
Re: Using an SD card in SD Mode
Low effort post incoming because I found myself with a a bit of time this afternoon as I lost my business analyst.
There's been a bit of discussion around SD cards so I decided to dump of where I am with SD card access so far. For those wondering I'm trying not to use programmable ICs and I'm accessing the SD card in 4bit SD mode which is where the absolute proliferation of 74 series ICs comes from.
Nope, no schematic or anything so profound. Proper low effort. The theory is that reads must be fast and should require no processor intervention once started. 512byte SD block reads are configured in the SD Card Read Function board as are the 16byte (? - I'm to lazy to check) CRC reads. They're ticked out into the W65C816s main memory address space by the 24bit Counter board.
The state of the read: waiting to start, reading data, reading the CRC or setting the done interrupt; are controlled by the SD card Read Signals board as well as whether the high or low nybble is being read from the SD card. Those nybbles are buffered and built into a byte in the SD Card Read Data board. The SD Card Clock board tries to control the madness and make sure that bytes are available to the main memory bus timeously. The CRC is ticked out of the SD card by the read circuitry but it is not checked for correctness.
Writes are much simpler as a byte is written to the device and then ticked out to the SD card over two clocks as the high and low nybble. The CRC must be calculated by the '816 and ticked out following the data bytes.
The Device Buffer board is a standard Device component that turns the 17bit Device address bus and 8bit device data bus on or off depending on the device select signal. It also handles device presence, enable, reset and interrupt signals. Device accesses always clock stretch the '816. How many cycles long the stretch is is controlled by the Clock Hold Standard board and depends on whether the device identifier ROM, onboard device RAM or device registers are being accessed.
The Device Decode A board decodes the device address into device identifier ROM select, device RAM select or device registers select. The Device Decode B boards decode 8 device registers each - split into read and write signals.
The Main Memory Data and Main Memory Address boards turn the main memory address buses on and off. Main Memory is access is never clock stretched. The W65C816 is taken off the bus when main memory access is happening.
The Flags and Interrupt board controls resetting the device as well as setting and clearing the device IRQ. The generic 6bit flags control which SD card socket is selected.
And somehow this has taken me 30 minutes to type already. So... happy sleuthing and kudos to you if you can work out what is going on from the pictures
(And the back of the board that has the important socket signals on it)
There's been a bit of discussion around SD cards so I decided to dump of where I am with SD card access so far. For those wondering I'm trying not to use programmable ICs and I'm accessing the SD card in 4bit SD mode which is where the absolute proliferation of 74 series ICs comes from.
Nope, no schematic or anything so profound. Proper low effort. The theory is that reads must be fast and should require no processor intervention once started. 512byte SD block reads are configured in the SD Card Read Function board as are the 16byte (? - I'm to lazy to check) CRC reads. They're ticked out into the W65C816s main memory address space by the 24bit Counter board.
The state of the read: waiting to start, reading data, reading the CRC or setting the done interrupt; are controlled by the SD card Read Signals board as well as whether the high or low nybble is being read from the SD card. Those nybbles are buffered and built into a byte in the SD Card Read Data board. The SD Card Clock board tries to control the madness and make sure that bytes are available to the main memory bus timeously. The CRC is ticked out of the SD card by the read circuitry but it is not checked for correctness.
Writes are much simpler as a byte is written to the device and then ticked out to the SD card over two clocks as the high and low nybble. The CRC must be calculated by the '816 and ticked out following the data bytes.
The Device Buffer board is a standard Device component that turns the 17bit Device address bus and 8bit device data bus on or off depending on the device select signal. It also handles device presence, enable, reset and interrupt signals. Device accesses always clock stretch the '816. How many cycles long the stretch is is controlled by the Clock Hold Standard board and depends on whether the device identifier ROM, onboard device RAM or device registers are being accessed.
The Device Decode A board decodes the device address into device identifier ROM select, device RAM select or device registers select. The Device Decode B boards decode 8 device registers each - split into read and write signals.
The Main Memory Data and Main Memory Address boards turn the main memory address buses on and off. Main Memory is access is never clock stretched. The W65C816 is taken off the bus when main memory access is happening.
The Flags and Interrupt board controls resetting the device as well as setting and clearing the device IRQ. The generic 6bit flags control which SD card socket is selected.
And somehow this has taken me 30 minutes to type already. So... happy sleuthing and kudos to you if you can work out what is going on from the pictures
(And the back of the board that has the important socket signals on it)
Re: Using an SD card in SD Mode
SD mode in 74 series? That is hardcore. Much respect.
For what it's worth, I'll attach the latest version of my SD code. Again, it's not directly usable for anyone who's not using my 65020 CPU. But it might be a useful guide to anyone attempting to do this themselves. I finally got around to implementing block_write in this one, and it will re-initialise if it gets a card-change interrupt.
For what it's worth, I'll attach the latest version of my SD code. Again, it's not directly usable for anyone who's not using my 65020 CPU. But it might be a useful guide to anyone attempting to do this themselves. I finally got around to implementing block_write in this one, and it will re-initialise if it gets a card-change interrupt.