Speeding Up Software Development Cycle for a 6502 using MacOS

Speeding Up Software Development Cycle for a 6502 using MacOS

Background

The purpose of my 65C02 project is self-education and fun.  It has provided both in abundance over the last 6 months and now includes:
  • 65C02 running at 2MHz
  • Power & reset module
  • 32k SRAM
  • 8k ROM
  • Address decoding logic to select various IO devices
  • MC6850 ACIA for serial communications
  • Hex keypad
  • 16 x 2 line LCD
Construction is on soldered prototype boards with point to point wiring (lots of it).  Each board has been developed as an add-on resulting in a less than optimum layout 😒

Until this point, each piece of assembler code I wanted to run had to be flashed to the ROM; that process entailed removing the ROM from the computer, using a EEPROM programmer (home-brew using an Arduino Mega) to flash new code then returning the IC to the computer.  Very slow and tedious.

Objectives

Recently I got a serial connection via USB to a laptop giving me a full keyboard and screen.  Now I want to develop my coding abilities and that means lots of development cycles, writing new code, loading it, running it and debugging it. 😬

My objectives were to:
  1. compile small sections of code and upload these to the 6502 RAM quickly and simply
  2. to execute code from a given address
Constraints:
  1. MacOS for editing code using VSCode
  2. USB serial interface to 6502
    6551 Serial Interface as an alternative to 6850
  3. A basic Monitor program on 6502 that only handles ASCII. 

First I evaluated of two strategies:

Binary file transfer 

VASM, my assembler can produce a raw binary file and I'd been using these for manual uploading.  The big downside is that my Monitor will not handle binary files.  I imagine something like Xmodem has been implemented, but that would be a big distraction for me right now.

Ascii file transfer

The basic monitor program already handles writing to memory from a starting address.  It expects to receive bytes as HEX pairs in ASCII and will load up to ASCII 255 bytes in one line.  There is no error checking.  This is the simplest but least robust approach but for small files of a few hundred bytes it would probably be ok to try.


First Solution - binary to Hex, then line by line upload

  • Running on MacOS I have VASM to compile source code and VSCode for editing.  A build task within VSCode runs VASM which outputs a binary file. 
  • XXD is a Linux command line utility that reads the binary file and produces a HEX dump.  It can be configured to write a fixed number of bytes then add a CR to create a text file consisting of HEX pairs in ASCII in lines of a fixed length, terminated by a CR
  • The HEX file needs to be sent to the 6502 one line at a time.  I use CoolTerm to handle this.  It provides a serial console connection to the 6502 through a 6850 ACIA.
  • A monitor program (based on WOZMON) runs on the 6502 and waits for characters coming from the ACIA.  The write command looks like this: W aaaa:HH HH HH <CR>.  W = write, aaaa = starting address, HH = HEX pair as ASCII.  The line ends with a CR and the data is then loaded into RAM.
  • CoolTerm will send one line at a time and wait for a preset delay before sending the next line - 150mS works well for me.  During this delay the monitor program is storing the received string into RAM.
  • I used a line length of 50 HEX pairs (equivalent to 50 binary bytes) per line.
The steps are:
  1. Write source code
  2. Compile to produce binary object code
  3. Convert binary to HEX ASCII file with 100 characters per line (= 50 bytes of binary)
  4. Connect to 6502 through a serial interface
  5. Run monitor and start Write (W) command
  6. CoolTerm sends lines of 100 characters with a 'Send String' command which also can read from a text file.
😰 - that is complex and error prone so I used a combination of a BASH script and an AppleScript.  It took quite some time to get all the parameters configured and passed correctly (there are still known bugs to resolve) but eventually the process becomes:
  1. Write source code
  2. Compile to produce binary object code
  3. Run AppleScript (and watch for errors).  Remember to modify the script to load the code at the intended address.  The AppleScript keeps count of the bytes sent and increments the starting address for each line.
😁 Much better but still some serious limitations:
  • my ability to write error free scripts that handle all situations!
  • no error correction
  • starting load address needs to be hard coded into BOTH the source code AND the AppleScript so is prone to errors

Improved Solution - Enhanced WOZMON that handles Intel Hex files

Whilst reading about WOZMON, the monitor written by Steve Wozniak in 1976 for the Apple 1,  I happened on a version that had been enhanced to handle Intel Hex files with error detection which looked very promising.  So I first adapted WOZMON to run on my system with input and output through a serial interface.  Turned out this was not too difficult and I was very excited when WOZMON was running - now my computer really felt like it came from the 70s!

Next I modified the enhanced WOZMON (eWOZMON) to work on my system using serial input and output.  Again it turned out to be straightforward.

Now if I had a file in Intel Hex format I should be able to upload it.... but VASM won't output in that format.  The key to this solution turned out to be a suite of programs called Srecord (spec_cat is the main tool).  This is an awesome utility originally designed to process Motorola srecords but now extended to work with a long list of file formats related to EEPROM programming.  Happily VASM, my assembler will output in srecord format so it was easy to convert this into Intel Hex file using srecord_cat.

The build process including converting to Intel Hex can be run with a keyboard shortcut within VSCode as it consists of two command line steps:
  • compile using VASM
  • Convert SRecord to Intel Hex file format using srec_cat
The final step is to upload this Intel Hex file to the 6502 and this is easy with eWOZMON and CoolTerm: send "L" to the monitor then select and send the Intel Hex file.

😄 Happy Days!  Now the process is:
  • Write source code
  • Compile and produce Intel Hex file (one command)
  • Switch to CoolTerm and upload file
The benefits are massive compared to both the original manual process and the first solution above:
  • error checking
  • load address is transferred with the data - no errors
  • Only two windows open - VSCode for editing and CoolTerm to work with the 6502
  • fast
  • error free - no dependency on my dodgy scripts!
This is what it looks like in practice :


Useful References

CoolTerm            https://freeware.the-meiers.org
srecord                http://srecord.sourceforge.net

eWOZMON:        
Apologies to the author but I could not identify you from a very old post.  Great work though.  My version modified to work with serial IO is here: https://gist.github.com/b529a24f39bcbd53f1e21775e24d0b9e



Comments