Thursday 18 May 2023

6502 : BEN2 : Xmodem

The Xmodem protocol

Xmodem has been used to transfer files over serial connections for about 40 years.  It was designed to be simple and easy to implement on different machines.  It incorporates error checking as it could be used over slow low-quality telephone lines.  Back in 1984 I used it to transfer files between PCs with cross-over cables and also to communicate between commodity traders in London and New York.

For the protocol to work between two local machines they need to be connected using a cross-over cable.  The transmit (TX) pin on the first computer is connected to the receive (RX) pin on the second, and vice versa.  The sender program prepares a file ready to be sent over the comms line and waits.  The receive requests the sender to start transmitting 128 data byte blocks.  Each block starts with SOH (Start of Header), contains a block number in the header and a check sum in the trailer so the receiver can verify data.  The receiver acknowledges (ACK) or reports an error (NAK) causing a new block or the same block repeated to be sent down the wire.  On completion the sender transmits an EOT (end of transmission) byte.

6502 implementation

I found a 6502 xmodem implementation by Daryl Rictor and have based my work on his xreceive program.  The PC xmodem implementation is available in ExtraPutty, a version of the Putty terminal emulator with added file transfer capabilities.

I started an xmodem implementation in August 2021 but ran into difficulties for a number of reasons:

    My breadboard hardware was unreliable
    I couldn't run my 6502 system at the full 1MHz speed
    My library system was not robust and wrong versions were used
    My understanding of xmodem wasn't very good
    It was difficult to see what was happening on the serial wire, particularly when bytes were missing.

These factors meant that, although I had some success, I couldn't get the protocol working reliably despite expending a lot of effort on the work, especially lots of time troubleshooting with trial-and-error solutions.  The result was that I shelved the project and after some time decided to build BEN2 in the hope that it would be more successful because:

    I have used soldered connections on stripboard
    I am already runnig the clock at 1MHz for testing terminal programs
    I am not going to use libraries during development
    I understand xmodem a little better
    My serial interface seems more stable

Approach

On the 6502 monitor program which is loaded when BEN2 is turned on or RESET, there are options to jump to a memory address to run a program and to look at the data at specific RAM addresses.  These are very useful for xmodem testing so I need to keep the monitor loaded.  Consequently I added the 6502 xmodem receiver as a monitor menu option / subroutine rather than a standalone program.

Rather than try to implement a full xmodem client initially, I wrote my own "cut-down" version of the "sender" in C on the PC and I then understood more precisely what was being sent down the line and I could write a corresponding "receiver" on BEN2.

Windows Subsystem for Linux (WSL) allows you to use serial ports and although the parameters for opening a port are somewhat esoteric, copying a sample from Google make it easy to try out.  As I wrote the sender program previously I only had to change the COM port number used to work for this implementation.

One snag with avoiding Putty for the download is that it is necessary to stop using Putty terminal emulation whilst downloading.   As I use the terminal extensively for my monitor program to control BEN2 this is a nuisance.  However, at least for the moment, it isn't too onerous to "hang up" before starting the sender program and "restart session" afterwards.


Simple code to download and execute a program

As xmodem (xm) is a subroutine my starting point for the receiver was the monitor program.  The first version added 'x' to the monitor menu to initiate the receiver and wait for something to be received on the ACIA/UART.  It simply saved the first four bytes received in memory address $1000-$1003.
I could then look at those RAM locations using the monitor.  The first three bytes received are the header and the fourth byte is the first character of my program data (just a string of text to begin with).

The next xm version downloaded 133 bytes to RAM starting at $1000.  This represents an entire block:

   <SOH><BlockNum 1><BlockNum 2><n program bytes><128-n filler bytes><checksum 1><checksum 2>

Again I could look at it in memory and check that all bytes were received.  I was very pleased to see that my receiver isn't dropping any bytes when the 1MHz crystal is used for 6502 clock.

I could now try to download a real program providing it was less than 128 bytes.  The program, which can turn an LED on or off is shown below.

I couldn't actually copy my existing blink program as it is compiled to run at $1000 and this new program was being loaded at $1000.  However it was easy enough to manually translate the program to machine code and type it in to my hex editor.
The ACIA addresses for PORTA LED are $6003 (for the Data Direction register A) and $6001 (for PORTA data).  The appropriate address to jump back into the monitor in completion is $8013.
To turn the LED on I entered the monitor command "j1000"; to turn the LED off the command is "j100d".

Multiple blocks

The previous xm version only allowed programs upto 128 bytes to be downloaded in a single block.  It was easy to extend the code to process multiple blocks which are saved contiguously in RAM.  The complete subroutine is shown below.




Verdict

This is very exciting.  I have a simple application which enables me to download an executable program from my PC to BEN2 and run it, without using a ROM programmer or an Arduino to perform the downloads.  

It is only a prototype, it doesn't implement xmodem protocol fully and has a lot of rough edges but it does form the basis for a working system which I can build on.



Nezha : Ubuntu rises from the ashes

 Intro

In April I was looking into using FEL mode on nezha and I was experimenting with using a SD card to boot into FEL mode.  The investigation didn't go well and resulted in a number of failed attempts with a selection of SD cards.  As frustration increased, almost inevitably, I overwrote my working system SD card with a duff image making it unuseable.  Luckily the Linux partition could be mounted on another system and I was able to copy off my data which comprised all my Risc-v assembly programming endeavours.  I then set about building a new linux environment for the Nezha

Ubuntu

I had a number of choices available to me.

  • The original Sipeed Debian 0.3 release from May 2021
    Unfortunately this image is no longer updateable
  • RVBoads 0.5 image
    This is the image I was using and which was destroyed.
    I knew the image I was using was not updateable, and a new copy I created had the same problem.
  • RedHat Fedora
    I don't really want to start using Fedora again
  • Ubuntu
    Sunxi provided links to some D1/Nezha Ubuntu images, in particular 22.04 and 22.10
    On investigating the Ubuntu Risc-V downloads for D1 I found there was a brand new 23.04 release.
    Initially I installed the 23.04 release but found it extremely slow.
Finally I settled on installing Ubuntu 22.10 release from the list provided by sunxi which appears to work well.

Installation


The Ubuntu 22.10 image doesn't require the strange Allwinner Phoenix SD card creation tool.  I simply used the linux dd utility to copy the image to an SD card.

I connected an FTDI cable to the serial pins, thoughtfully provided and labelled on Nezha

I could then boot up the SD card and was somewhat excited to see it burst into life:


After quite a while (7.5 minutes) the login prompt was displayed.
Subsequent startups were still quite slow (about 3 minutes) and login is very slow but the system behaves well once you are logged in.
By default there isn't a desktop GUI, which is fine by me.  Even if I wanted one it would be sluggish on the Nezha.

Configuration

As usual I setup a static IP address.  I haven't used Ubuntu before and needed to familiarise myself with the netplan command line tool for setup.
I could then copy SSH keys across from Windows so that I have automatic login from WSL.

As 22.10 is an older release there were lots of updates to apply (111 packages) however the process went slowly but smoothly.  I was also given the option to update to 23.04 but I declined.

Other software installed:
lighttpd - my favoured simple webserver
samba - to easily swap files with windows; I map a drive in Windows to /root/sambashare for copies.
gcc - not installed by default, I need it for my risc-v C and assembly lessons.

Restore

Once I was happy with my system I could restore my C and assembly programs and related libraries.  My system is now back to life, with its data and in good health with updateable software.