Monday 9 August 2021

6502: Download programs to RAM

 My current mechanism for loading programs onto 6502 is to use the Arduino Mega to download machine code to ROM.  Although this is a vast improvement on using an Eeprom programmer it is quite slow, particularly for C programs which tend to be larger.

It would be preferable to use the 6502 serial interface to download a compiled program to RAM where it cn be executed.  This is analagous to loading a program from disk into memory and running it.  I still expect to save completed programs and subroutines in ROM, but this scheme should make the development cycle easier.

Both Extraputty and TeraTerm provide xmodem transfers.  Daryl Rictor has provided a sample xmodem implementation for 6502 so I have the basic ingredients available to me.

My objective is to take a machine code / hex program from the PC, transmit via USB serial port to the ACIA 6551 then read it in to RAM where it can be executed.

Initial tests did not go well. I dont have the ability to log the character string that Extraputty / xmodem is sending or an understanding of the protocol or much idea of how the receive program works.  The trial and error method is somewhat doomed.

The xmodem protocol is intended to be simple to implement, a major factor in its long term popularity. 

 
Data is downloaded in 128-byte packets.
Each packet has a 3 byte header: <soh=0x01> <block number> <inverted block number>
There is also a 2 byte trailer containing a CRC code.
This makes a total of 133 bytes

The receiver sends a character 'C' to the sender to start transmission.
Sender responds with a packet (133 bytes) which the receiver acknowledges with <ACK>.
The receiver carries out block number and CRC checks, if they fail the receiver sends <NAK> instead of <ACK> and the sender retransmits.
This is repeated until all packets are sent, at which point the sender sends <EOT=0x04>

To simplify testing I wrote a C program on my PC which sens a single xmodem format packet to the 6502.  I was pleased to find that Windows/WSL allows me to use a PC COMnn port as /dev/ttySnn providing the program has sudo privileges.  It is a bit fiddly to configure the settings but straightforward if you have a good tutorial .  The completed program looks more complicated than it is. 

Unfortunately, even with a known test program I couldn't make xmodem work. My 6551 works fine but my system or ExtraPutty may be incompatible in some way with Daryl's xmodem example.

I then decided to write my own xmodem receiver.  I simply have to read in some data packets, in a known format, into RAM using my existing subroutine library and I have Daryl's example for hints and guidance.  As we are using a short local connection I can skip the error checking - if an error occurs I would just reload the program.

This approach is much more successful.  I can take an executable program, created using cc65 on the PC and transfer it to 6502 RAM.  After checking using the monitor that my first program was transferred successfully to RAM address $1000 I tried to run it but (of course!) it failed.  The program had originally been compiled to run at $8000.  Once I changed the .org statement to rectify this it ran fine.  I would include an  image but the test program just displays a '#' character and allows character input.

This is an excellent result.  Although there are currently a number of rough edges to smooth over we have a working solution.  It allows us to reduce reliance on the Arduino Mega and the expectation is that it will accelerate downloads and speed up my development cycle (which involves frequent program changes).

No comments:

Post a Comment