Fastest possible SD card Read with a 6522 VIA?

For discussing the 65xx hardware itself or electronics projects.
Dietrich
Posts: 45
Joined: 01 Jan 2003

Re: Fastest possible SD card Read with a 6522 VIA?

Post by Dietrich »

Quote:
... remembering that the data stored at the SSR must have its bits flipped, since the 6522 SR is least significant bit first rather than most significant bit first.
The 6522 SR is MSB first!

Dietrich
My system: Elektor Junior Computer, GitHub https://github.com/Dietrich-L
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Fastest possible SD card Read with a 6522 VIA?

Post by GARTHWILSON »

Right.  It's the '51 and all UARTs that go lsb-first.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
fachat
Posts: 1123
Joined: 05 Jul 2005
Location: near Heidelberg, Germany
Contact:

Re: Fastest possible SD card Read with a 6522 VIA?

Post by fachat »

While there is much talk about just receiving the data with the SR (or in general). SPI is a bidirectional protocol, you need to be able to send commands as well.

So, if you use the VIA SR to receive data, I assume to get as fast as you can, you use Phi2 clock input for the SR. that means that you need to use CB1 clock output as source for the SPI clock. And then you end up in the mode 0 / mode 3 mess already again, right? I even wonder how you are going to receive mode 0: data is shifted out when /SEL activates (first valid bit), and on falling clock of SCLK. If you use the inverted SR clock as SPI clock, you shift the data in exactly when the device already shifts out a new bit. That typically works if the device goes by the "specification". I've done that as well, but it is not a good design. You would need a delay circuit for the clock anyway, as Bruce has proposed in the other thread.

But how are you going to send data? If you switch SR direction, you need to switch SR output CB2 between MISO and MOSI, which costs additional gates and a gate that switches direction.

You can bit-bang data out on MOSI - but then you need to have a way to send pulses on SPI clock also - despite it is driven by SR clock (CB1) when receiving. Again additional gates.

Ok, at a minimum hardware you could use an NAND between CB1 and a port bit used as SPI clock output when sending to drive the SPI clock, put MOSI from another port bit and MISO to the SR input. But that means that anytime you want to send data you have to bit-bang it. (Note that I'd probably use the clock delay from here download/file.php?id=20395&mode=view and connect the output clock port bit to IC2 pin 12, to have a more compliant SPI mode 0 clock).

Yet, at the cost of that single external serial-to-parallel shift in chip, I firmly believe that this download/file.php?id=20395&mode=view is a very balanced and efficient approach in terms of hardware and software used, and provides full speed in both directions.

Code: Select all

     BIT PORTA   ; trigger /ACK for clock circuit 
     ; ... per byte
     STA SR      ; trigger transfer
     LDX #$FF
L0   LDA #4
L1   BIT IFR   ; check 
     BEQ L1
     LDA PORTA  ; read incoming data 
     STX SR    ; trigger next transfer (by sending $ff in this case)
     ; process received data (e.g.)
     STA (ZP),Y
     INY
     BNE L0
If you count clock cycles, and your processing time is long enough, it may even be possible to remove the IFR check.

You may need to be careful with the end condition.
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/
BruceRMcF
Posts: 388
Joined: 21 Aug 2019

Re: Fastest possible SD card Read with a 6522 VIA?

Post by BruceRMcF »

Dietrich wrote:
Quote:
... remembering that the data stored at the SSR must have its bits flipped, since the 6522 SR is least significant bit first rather than most significant bit first.
The 6522 SR is MSB first!
Oh my goodness, I was misreading the datasheet ... all of the timing diagrams say "1" through "8" on the serial data line, but the notes on page 21 say that bitt7 is shifted out first and bits are first shifted into bit0.

~~~~~~~~~~~~~
fachat wrote:
While there is much talk about just receiving the data with the SR (or in general). SPI is a bidirectional protocol, you need to be able to send commands as well.

So, if you use the VIA SR to receive data, I assume to get as fast as you can, you use Phi2 clock input for the SR. that means that you need to use CB1 clock output as source for the SPI clock. And then you end up in the mode 0 / mode 3 mess already again, right? I even wonder how you are going to receive mode 0: data is shifted out when /SEL activates (first valid bit), and on falling clock of SCLK. If you use the inverted SR clock as SPI clock, you shift the data in exactly when the device already shifts out a new bit. That typically works if the device goes by the "specification". I've done that as well, but it is not a good design. You would need a delay circuit for the clock anyway, as Bruce has proposed in the other thread.

But how are you going to send data? If you switch SR direction, you need to switch SR output CB2 between MISO and MOSI, which costs additional gates and a gate that switches direction. ...
Yeah, just using the SSR as a dedicated MISO best fits a serial Flash, especially the 256 byte sector serial Flash, where you would typically be putting out a few bytes and then reading a sector. You need a single AND gate to merge the input byte serial clock from the SSR and the output byte serial clock from a GPIO, and that's it ... because serial Flash are typically Mode0/Mode3.

So that's pretty much a "minimum extra chips" circuit, thought the downside is that single logic gates tend to be in SMB packages.

But if you are even going to SPI mode SD, I reckon that the two chip circuit using the VIA SSR and a separate serial shift register is the way to go.
Dietrich
Posts: 45
Joined: 01 Jan 2003

Re: Fastest possible SD card Read with a 6522 VIA?

Post by Dietrich »

GARTHWILSON wrote:
Dietrich wrote:
The fastest Code to read a SD card is, to my knowledge, this one:

Code: Select all

SPI_BIN	LDA IFR		;read byte from SPI
	AND #$04	;test SR bit
	BEQ SPI_BIN
	STA IFR		;clear SR bit
	LDA SR
	RTS
How about:

Code: Select all

SPI_BIN: LDA  #4
 1$:     BIT  IFR
         BEQ  1$        ; (shorter loop)
         LDA  SR        ; (This clears the IFR's SR bit.)
         RTS

Perfekt. Thanks. I will use that for sure

Dietrich
My system: Elektor Junior Computer, GitHub https://github.com/Dietrich-L
User avatar
tius
Posts: 41
Joined: 05 Nov 2021

Re: Fastest possible SD card Read with a 6522 VIA?

Post by tius »

If CA2 and the shift register cannot be used, these is the fastest solutions I have found so far if MISO can be connected to PA6 or PA7:

MISO connected to PA6

Code: Select all

    lda #0
    ldx #BITS_CS_LO
    ldy #BITS_CS_LO | BIT_SCK    

    sty SD_PORT                 ; 4     set sck hi
    bit SD_PORT                 ; 4     test miso
    stx SD_PORT                 ; 4     set sck lo
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$80                    ; 2     set bit 0

    sty SD_PORT                 ; 4     set sck hi
    bit SD_PORT                 ; 4     test miso
    stx SD_PORT                 ; 4     set sck lo
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$40                    ; 2     set bit 0

    sty SD_PORT                 ; 4     set sck hi
    bit SD_PORT                 ; 4     test miso
    stx SD_PORT                 ; 4     set sck lo
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$20                    ; 2     set bit 0

    sty SD_PORT                 ; 4     set sck hi
    bit SD_PORT                 ; 4     test miso
    stx SD_PORT                 ; 4     set sck lo
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$10                    ; 2     set bit 0

    sty SD_PORT                 ; 4     set sck hi
    bit SD_PORT                 ; 4     test miso
    stx SD_PORT                 ; 4     set sck lo
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$08                    ; 2     set bit 0

    sty SD_PORT                 ; 4     set sck hi
    bit SD_PORT                 ; 4     test miso
    stx SD_PORT                 ; 4     set sck lo
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$04                    ; 2     set bit 0

    sty SD_PORT                 ; 4     set sck hi
    bit SD_PORT                 ; 4     test miso
    stx SD_PORT                 ; 4     set sck lo
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$02                    ; 2     set bit 0

    sty SD_PORT                 ; 4     set sck hi
    bit SD_PORT                 ; 4     test miso
    stx SD_PORT                 ; 4     set sck lo
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$01                    ; 2     set bit 0
~124 cycles per byte (depending on the bit values), should work with any bit order or polarity.
Last edited by tius on Thu Dec 26, 2024 1:36 am, edited 2 times in total.
User avatar
tius
Posts: 41
Joined: 05 Nov 2021

Re: Fastest possible SD card Read with a 6522 VIA?

Post by tius »

If CA2 and PA7 are available, this code allows the remaining port lines to be used for other purposes.

Code: Select all

    ldy #$7f

    cpy SD_PORT
    rol
    cpy SD_PORT
    rol
    cpy SD_PORT
    rol
    cpy SD_PORT
    rol
    cpy SD_PORT
    rol
    cpy SD_PORT
    rol
    cpy SD_PORT
    rol
    cpy SD_PORT
    rol
48 cycles per byte.
Last edited by tius on Wed Dec 25, 2024 11:37 pm, edited 1 time in total.
User avatar
tius
Posts: 41
Joined: 05 Nov 2021

Re: Fastest possible SD card Read with a 6522 VIA?

Post by tius »

If CA2 and PA6 are available, the following code should work:

Code: Select all

    bit SD_PORT                 ; 4     test miso
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$80                    ; 2     set bit 0

    bit SD_PORT                 ; 4     test miso
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$40                    ; 2     set bit 0

    bit SD_PORT                 ; 4     test miso
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$20                    ; 2     set bit 0

    bit SD_PORT                 ; 4     test miso
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$10                    ; 2     set bit 0

    bit SD_PORT                 ; 4     test miso
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$08                    ; 2     set bit 0

    bit SD_PORT                 ; 4     test miso
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$04                    ; 2     set bit 0

    bit SD_PORT                 ; 4     test miso
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$02                    ; 2     set bit 0

    bit SD_PORT                 ; 4     test miso
    bvc *+4                     ; 2/3   branch if miso is low    
    ora #$01                    ; 2     set bit 0
~60 cycles per byte (depending on the bit values).
Post Reply