TomNisbet / TommyPROM

Simple Arduino-based EEPROM programmer
https://tomnisbet.github.io/TommyPROM/
143 stars 29 forks source link

Read and Xmodem-CRC save command failing with minicom (and suggested fix) #14

Closed NigelTwo closed 3 years ago

NigelTwo commented 3 years ago

I built the TommyPROM project with the intention of archiving a pile of ~35+ year old EPROMs. I assumed that the Xmodem transfer works with some terminal program, probably on a Windows or Mac Operating System. But the transfer always failed on Ubuntu Linux using minicom (which invokes a unix program named rx to receive the file). Here is an explanation of the fault and a simple fix.

An Xmodem protocol explanation can be found by searching for e.g. "MIT XModem protocol with CRC". It is a character based protocol easily as old as my EPROMs!

The TommyPROM Xmodem.cpp source file has a function called SendFile() that controls the transfer. After the last packet is sent, it sends an EOT character and terminates with success, not waiting for the final ACK from the receiver. Two things now happen:

  1. Control returns to the main loop() which finds there is a command status message to send. It immediately sends it (INFO: blah) to the Xmodem receiver, which looks like further packet characters to "rx". "rx" then chokes and starts to NAK and CANcel. Bad.
  2. The positive ACK character is received by the main command loop and this causes the next user command in TommyPROM to fail (because the ACK character is in the command buffer) Worse, the ACK it has been echoed back to the Xmodem receiver. Phew!

A suggested fix is simple. Consume and process the character returned from the EOT packet in the SendFile() function before returning viz ` Serial.write(XMDM_EOT);

// Consume the expected ACK response rxChar = GetChar(5000); if (rxChar != XMDM_ACK) { cmdStatus.error("Expected XModem ACK to EOT, but received:"); cmdStatus.setValueDec(0, "char", rxChar); return false; } return true; } ` The command status message (INFO: blah) is still lost unless the terminal program is very quick to revert. But it is displayed on the next menu refresh.

Thanks again Tom for putting this all together. I sense success is close for me.

TomNisbet commented 3 years ago

@NigelTwo - I'll revisit the protocol spec to see if there are other areas to tighten up as well. I use this with TeraTerm on the PC and it worked, but it may be the case that TeraTerm just fires the ACK and quits, so it doesn't get bothered by the garbage after it. I'll fire up a Linux machine and will test to make sure everything looks good with your fix.

Please let me know what sorts of ROMs you are reading. It's always good to know what people have been able to do with this. I've been able to read a bunch of my old ROMs with this design with just the minor wire changes for the address line differences. The first use of the design was to read the 2716 Basic ROMs from my old 8085 machine.

Thanks for the detailed bug report. I should be able to get this wrapped up quickly.

NigelTwo commented 3 years ago

@TomNisbet - Just as well to verify the operation on TeraTerm (Windows only I see).

ATMega328 might only be a microcontroller, but it is astonishingly fast at producing serial data. By the time those "post EOT" characters have been buffered by the serial-to-USB chip, then the OS hardware driver, and finally delivered into the OS they will look like a data packet headed with EOT. Xmodem was originally a half-duplex protocol, so there must have been an inter-packet silence that we now have to reproduce. I am guessing that a "false EOT detector" is triggered in this situation.

FWIW I have found that minicom has to be configured with no hardware and software flow control. Also the Xmodem helper program, "rx", is not part of minicom (it is part of the lrzsz package) and needs the -c option (configured in minicom) in order to receive CRC16.

Yes, I have 2716 EPROMs queued up to be read. They will need Vcc wired to pin26/A13 for a starter. I intend reporting back about this later.

NigelTwo commented 3 years ago

I verified the Xmodem transfer now works with minicom on TommyPROM V2.2 and v2.3. I programmed a 32KB image to an AT28C256 with a modified version of TommyPROM V2.0. The modifications were to support '595 shift registers. I read this EEPROM back (>R0 7FFF) to my host system using the later versions of TommyPROM with the new support for the '595 shift registers. The binary file compares exactly with the original image file. N.B. The support for the '595 shift registers is still being "ironed out", see #15. So some minor changes were required to the code. But these don't interact with the Xmodem save functionality.