Sunday, 11 June 2023

6502 : BEN2 : Xmodem Enhancement 2 : Flash programs to ROM

 Intro

Using the serial port for xmodem downloads has made the process of putting executable code into RAM a lot easier and we now have a very friendly environment for developing programs.

Previously I used an Arduino Mega to download programs to ROM for testing.  As serial downloads are more convenient I have removed the Arduino Mega from my system.  The Mega used to interfere with 6502 initialisation previously so the system is now more reliable.  In addition it was messy to have another board attached together with its PC USB connection.  However it does mean that I have no method for updating the ROM in situ.

Design

It occured to me that if I can write ROM from the Mega and write RAM from BEN2, I should be able to flash ROM from BEN2.  Looking at the Arduino sketch I was using, all I need to do in preparation was set ROM /OE pin high to disable ROM output and set ROM /WE pin low to enable writing.  I should then be able to write whatever I wanted to ROM before resetting the values afterwards to /WE=HIGH and /OE=LOW.  In fact my circuit used a pull-up resister on /WE and a pull-down resister on /OE so that by default, if the pins were not set the ROM would be in read-only mode.

BEN2's VIA chip provides GPIO capability so I can potentially connect two wires from my VIA chip to ROM/OE and ROM/WE and set them high or low as required.  Once that was done I could write data to ROM in the normal way using 6502 STA instruction.

There is one wrinkle I have to remember.  When ROM/OE is set low to disable output and allow new values to be input it is not possible to read machine code instructions from the ROM.  Consequently the subroutine which copies an executable to ROM must reside in RAM.

Proof of concept

I wrote a simple assembly program which stores a few characters (in fact the string "JOHN") to memory.  At first I set the target address as RAM and checked the data was stored properly using the monitor m-command to display a range of memory.
I have five VIA pins not used by the LCD PA0, PA1 (buttons) and PA2, PA3, PA4 (LEDs).  I attached wires from PA3 to ROM/WE and PA4 to ROM/OE so that when I set the values high or low I could see on the LEDs their status.  In my program I set PA3 low and PA4 high then wrote a string to an address ($9000) in ROM, then reset the pins to enable output and prevent writing.
The program worked fine, I was confident I could write data to ROM.

Attach a program

For the next few stages I practiced copying to RAM.  When this worked I would modify the program (slightly) to write to ROM.
My next program write-ramx used a loop to copy a sequence of bytes to RAM.  The target_address, data_length and data were specified in the program.  The Y register was incremented each time around the loop to copy to successive memory addresses.


I intentionally placed this data at the end of the program.  I then removed the data so that the last statement in the program was the label data.  Now I could take the executable write-ramx.x and append the program I wanted to copy at the end.  When I downloaded and executed write-ramx it copied the attached program to the target address.

In fact I also needed to encode the load address for write-ramx, the target_address and data_length in the download binary.  A complete binary takes the form:
   <\x00\x20><xmodem-3-write-ramx.x=70 bytes><\x00\x10><\x00\x16><via-3-LED-1x.x=22bytes>
In this example the load address for write-ramx is $2000, the target address for LED-1x is $1000 and the length of LED-1x is $0016.  I used a shell script to encode the addresses and length and to concatenate write-ramx with the payload program LEX-1x.  This package was then transmitted through the serial port to BEN2.

My simple program using the Y register as an index was limited to a maximum "8-bit" program size of 255 bytes.  For a full-sized program I went to 6502.org and found a "16-bit" copy subroutine by Bruce Clark called MOVEUP I could use. To use the subroutine I simply needed to specify a source address (the end of the program), a destination address (target_address) and size (data_length).
These were loaded directly from the executable into the program

Once this program was working I could arrange for BEN2 to go in ROM writing mode before the copy and reset afterwards.
The final program is shown below


Conclusion


My program write-romx now works.  In its final form it looks quite simple.  You set up the necessary addresses, enable writing to ROM, copy the data (i.e. payload program) and reset ROM to read-only.  The program is downloaded to RAM with a payload each time I need to put something into ROM.

Now I dont need to attach the Arduino Mega to write to ROM we are in a much better position.

In practice when developing programs iteratively I will usually load and execute them in RAM.  Once they are working I can use this method to copy them to ROM.

I have glossed over a few details here, partly because they aren't very interesting and partly because it is easy to become confused with the details.





No comments:

Post a Comment