Tuesday 4 July 2023

6502 : BEN2 : Monitor v3 finally released

Monitor v2

A couple of months ago, at the end of April, I attached an ACIA on a breadboard to BEN2 which gave me terminal access to the system.  Using the serial connection I was able to download programs from my PC to BEN2 using a simplified xmodem transfer.  In early May I setup monitor v2 which included xmodem file transfer and other basic functions such as memory display, jump subroutine and clear screen.  

For the reset of May I focussed on creating AMI, a daughter board for BEN2 "peripherals" comprising the ACIA, LCD, buttons, LEDs and clock.  By the end of this work I had a robust, soldered daughter board alongside BEN2, mounted on a perspex stand.  To make the system neat, pretty and more reliable I detached the Arduino Mega which I had previously been using to download programs.  This gave me a hardware setup which begins to look like a real computer.

Using xmodem, meant that I could download and run programs more quickly and easily to RAM.  I spent some time making the process more streamlined, quicker, easier, more predictable and making programs relocatable so that I could have multiple concurrent programs in RAM.

The downside of using xmodem and not having the Arduino attached was that I couldn't update ROM.  Luckily monitor v2 has proved very reliable and I have been using it without problems for the last couple of months.

I was reluctant to reconnect the Arduino Mega again to update ROM programs and my thoughts turned to how I could run a 6502 program on BEN2 to update its ROM.

Writing ROM

Ben Eaters 6502 design required the ROM to be removed for programming. BEN2 was setup specifically so that the ROM could be updated in situ using an Arduino Mega.  There are only a couple of extra hardware connections required to achieve this; specifically it was necessary to control ROM /WE and ROM /OE, the ROM write-enable and output enable pins from the Arduino.

After a little experimentation I developed a program write-romx, which runs in RAM and copies a program from RAM into ROM.  I set up write-romx so that I could download it from the PC with the program destined for ROM attached to the end of it.

I wrongly thought that I had nearly finished my work at this stage.  I had to change my terminal emulator to resolve an issue and tweak the timings to ensure bigger downloads were reliable.  I also found an irritating error, not yet resolved, which stopped me using various ROM load addresses.

In addition to writing programs to ROM, I need to be able to write individual bytes, for example reset vectors, and I developed a script, using write-romx, to do this easily.

Libraries

Once I had a basic method for writing to ROM, I started to work on a new monitor program.  Initially I could only write short programs and I realised I could use monitor-v2 subroutine in my new programs providing I knew their ROM addresses.  I developed a little shell script which analyses an assembly map and extracts address information to create a symbol table.  I arranged for the symbol table to be in the form of a header file, with all subroutine names prefixed with "LIB".  I could now use the monitor-v2 subroutines in any of my programs just by prefixing them with "LIB".  This kept my program code and download times much shorter.

My previous attempts at providing libraries were very frustrating as any errors in version or address of subroutines usually caused programs to fail and the update process was manual.

Programs

Now that I had a platform to develop / update programs for monitor-v3 I could put some effort into providing some extra functionality.  I decided I should focus providing a set of "driver" subroutines for VIA hardware and the terminal.

At present I am using the LCD screen and LEDs on VIA I/O ports.

There are quite a few capabilities within the HD44780 driver chip such as scrolling text, custom characters.  I decided I only want basic ones to control the LCD screen.  I made sure that I can clear the screen, display character output starting at any location on the screen, delete top or bottom row.  I wrote a test program VIAtest to test new and updated subroutines.

If I needed an existing subroutine within VIAtest I could use a monitor-2 LIB subroutine.
Some subroutines needed to be updated before use and I used a local version within the program, with the corrections / additions.

I only needed LED subroutines to turn the red, amber, green LED on or off.  I did provide a blink function but it is limited to a fixed duration as I don't have a "key pressed" interrupt or button capability to terminate blinking.

I developed TERMtest to provide extra terminal functions.  Various useful functions were added to:

  • write out a large block of text
  • position cursor at particular [row, column] position
  • change the colour for character display
  • erase screen and display menu



Building monitor-3

Monitor-3 started life as a minimal cutdown version of monitor-2 that I could fit into 512 bytes.  The minimal functions provided were m (memory dump), p (clear some memory), s (subroutine jump), x (xmodem download), z (return to monitor at next level).  It used monitor-2 library routines as far as possible.

There was a lot of work build monitor-3 ready for burning to ROM.

Firstly I took all monitor-2 subroutines (except any local ones) and copied them to three files depening on function TERM (terminal control), VIA (LED, LCD) and SHARE (utilities).  I added new subroutines from VIAtest and TERMtest into these files and replaced old versions with any that had been updated.  I also updated my symbol and zero page variable definition header file memory_map_v1 with extra symbols and zero page variable names for new and updated values from monitor-3, VIAtest and TERMtest.

Once I had tested monitor-3, VIAtest and TERMtest to make sure they still worked I sanitised the programs and include files to make sure they confirmed to some basic standards

  • Tab character at start of line before each opcode
  • Comments aligned consistently
  • Registers saved / restored in all subroutines - or reason for not doing so provided
  • "cheap" labels with local scope, beginning with "@", used in all subroutines

Thirdly I had to remove all "LIB" references in monitor-3, VIAtest, TERMtest to make sure that I have a consistent set of subroutines in monitor-3 and no dependencies on monitor-2 (which will be deleted soon).  This gave me three working programs using a set of tested subroutines, all of which were local to the program or in shared include files.  The programs were about 1kB-1.5KB in size. 

Finally I was ready to write the new monitor so I connected up my two ROM write wires and ran the write-romx program to save monitor-3 to $A001.
I saved a NOP code at $A000 (to circumvent my unresolved "lost byte" error) and changed the reset vector using a script to $A000.
I hit the reset button and saw...the monitor-3 menu 😀😀😀😀



I now have an updated monitor in ROM which forms a great basis for further development.

Concluding notes

The ability to develop programs easily in RAM and flash new monitor versions to ROM are great improvements.  My previous boards have all gone downhill as I added functions so it was important to me that I have a good environment to develop further ideas. 
Previously, the provision of the AMI daughter board was a big step forward making the hardware reliable.  Monitor-3 should provide a stable development environment, including the use of library subroutines and represents a similarly important step in making the software reliable.

In summary, this is wonderful because BEN2 is starting to feel like a (1980s) computer.

No comments:

Post a Comment