It was back in July when I last updated the monitor program which starts when the 6502 is booted. MON3 has proved to be very reliable, it has allowed me to forget about the details of downloading to RAM since it rarely goes wrong. Restarting BEN2 also goes smoothly most of the time so I can concentrate on new developments.
New Functionality
Since then I have focussed mainly on adding VIA functions to the system. I started off with all 16 VIA pins on ports A and B in use: PA0-PA1 are wired for buttons, PA2-PA4 are LEDs, PA5-PA7 and PB0-PB7 are used for the LCD display. The first enhancement was to add a 74HC595 shift register, as described by Garth Wilson which uses only three pins, CA2, CB1, CB2 all of which are available. It provides me with 8 extra pins and allows me to add an 8 LED bar (or 8 LEDs) I can easily chain further shift registers if I need more output pins.
Next I followed Ben's advice on VIA interrupt functions; an Interrupt Service Routine and Interrupt Vector were initially set up to process a button interrupt on CA1. At this stage I don't have anything specific which requires a button, so the ISR simply displays a letter on the screen.
VIA chips also provide two timers; I followed Ben’s tutorial to add a timer interrupt. Each 10ms timer interrupt causes the ISR to increment a clock tick. Using 100 ticks I can display a clock which increments each second. I can also schedule regular events such as an LED flashing in the background.
To facilitate background activities we minimise code in the ISR and add an idle loop to the monitor which constitutes a simple state machine. Whenever the monitor (or VIAtest) is waiting at the menu there is a check on the current tick count to determine whether other activities such as the LCD clock display or an LED flasher need updating.
The final major investigation was to add sound by setting up a buzzer. It is a very easy addition, simply toggling an output pin with a speaker attached many times a second to generate a sound. This exceeded expectations, the sounds are good and I can control VIA output to generate sounds of varying pitch. This allowed me to play different notes, scales or tunes on BEN2, culminating in a rendition of three blind mice.
I still have a shortage of VIA pins so I changed over the LCD instructions from 8-pin to 4-pin. The updates are quite straightforward. Changing from 8-bit to 4-bit operation was a problem until I found it requires a magical reset sequence . PB0-PB3 have now been freed up for other purposes.
At this stage I decided that I have plenty, maybe too many, changes for the current release and that I should leave hardware updates to the next release.
System Updates
Most of these changes don’t affect the monitor program itself, they provide extra or updated versions of subroutines used by other programs. Since I bundle all ancillary subroutines with the monitor when I save it to ROM I can release them all together. The monitor does need to be updated to include an ISR and to allow other processing to be carried out whilst waiting for user input. It also includes a couple of extra menu options. The “write byte” option has been added to update a single byte of ROM or RAM and I added an option to turn off interrupts when not required.
MON3 is stored at $A001 in ROM so I can save MON4 at $8001 and test in parallel, without destroying the ability to use MON3.
1 The write byte option has already been incorporated in the RAM development version of MON4 so I could write MON4 to ROM and I verified that it continued to work as expected.
2 I added the Interrupt Service Routine to MON4 at $8004 and set the reset vector at $FFFE-$FFFF to $8004 using "write_byte". MON3 didn't use interrupts so this change didn't affect its operation.
3 I have started to use Dirk Grappendorfs macros to save and restore A, X, Y registers on entry / exit to subroutines. There is a convenient macro to load a 16-bit memory pointer.
4 I tried to rationalise zero page memory variables / usage. I now have three 16-bit registers R0,R2 and R4 or alternatively six 8-bit registers R0, R1, R2, R3, R4, R5. I setup local names within subroutines which can rename these page zero "registers" to be more meaningful in particular contexts.
5 Tests to terminal and shared routines were quite straightforward. The main one was to add Binary Coded Decimal (BCD) conversion to SHARE. BCD converts a binary number to a decimal one; Ben dedicated a whole video to setting it up so I expect to to be useful.
6 I added the button and timer interrupt routines to MON4, these are specific to the ISR so I keep them local to MON4.s rather than adding to shared routines.
Once I added interrupt processing other options (s-subroutine jump, x-xmodem download) stopped working so I make sure that interrupts are turned off before moving to other programs.
7 I added VIAtest subroutines for shift register processing to VIA.s
8 I added VIA Sound subroutines to VIA.s so that any program can play buzzers / musical notes.
9 I changed LCD operation over from 8-bit mode to 4-bit mode.
Once all functionality has been added I could change the reset vector from $A001 (MON3) to $8001 for MON4 using Write Byte. We now have a new monitor.