So my transfer routine has been a little flaky lately. I’m not sure exactly why but I think it’s related to the number of processes I’m running. While it’s a P4 2.4, I think USB scheduling is dead last on the priority list, because it sure seems that way. My transfer protocol is pretty simple right now, or almost completely non-existent. After the PC sends a R for ReadDisk, the SX starts spewing data. There is no handshake, no acknowledgement of data — but there is a checksum. And that checksum has been failing. While I do initiate auto-retransmit, its slow and clumsy.
So tonight, I implemented an XMODEM-like protocol. Sender and receiver synchronize the start, each block is acknowledged, a NAK causes a retransmit of a block, instead of the whole track, and so on. and overall it works pretty good except for one thing. IT’S SLOW. How slow? About 2.1s per track. Yuck. At my high point with the other transfer, I was around 313-328ms per track. So like 6 times faster.
That’s way too slow. There’s a lot of back and forth with this protocol, with forced acknowledgment before the next block is transferred. The wikipedia page on Xmodem said that was one of the reasons for its replacement with other protocols like Ymodem and Zmodem.
Incidentally, I grew up on these serial based protocols, and used everything from Xmodem to Kermit to Ymodem, CIS B+, etc on BBS’s. ZModem with it’s resume feature was really tits on a stick back in the day.
Part of my problem is block size. I’m actually using 32-byte blocks because I don’t have enough memory on my SX. So that’s 374 blocks per track. 374 headers, 374 ACK’s.
34 blocks per sector, 172ms per sector. Just way way way too slow.
Since before I read from FRAM directly to USB, there was effectively no easy way to retransmit, because you can’t just backup using serial memory. And I don’t actually keep track, use, seek, of any fram byte locations. I don’t need to — I write one bit at a time, and I read back one byte at a time — but always in order, and always from start to end. The way I retransmit now is to re-read the track into memory again, and start the process all over again. In the past this worked for the few times I needed, but it seems that for whatever reason (maybe new FTDI drivers?) I’m dropping much more regularly now.
This xmodem method isn’t really 100% polished yet, but given these times I think it’s unlikely I’m going to. Gotta come up with a better method. Some in-between. Maybe some FRAM re-positioning routines?
I’ve love to hear what YOU think.
Soo, I think the plan is to:
1. rewrite my findsync() routine that looks for the syncword on the disk, and positions the FRAM properly. While it will still do this, I’m going to add functionality that keeps track of the 2-byte memory address AND the bit-offset (0-7) that the sync was found at.
2. Write a routine that will position the fram at an exact byte & bit offset.(right now, the FRAM has an opcode for reading a particular address, I basically just have to add a little routine that reads x number of bits into the next byte) This will allow me to go back, and retransmit blocks.
3. Implement something similar to what I just did using Xmodem, but using much larger blocks. I have to transmit 11968 bytes total, and the USB buffers max out around 4k. So Maybe 2,992 bytes per block. 4 blocks. Much less back and forth.
While I haven’t got much to comment, here’s a link to a similar project undertaken among EAB members:
Quite a bit of sofistication and planning, that kind of stuff I hope you like 🙂