USB Mouse for 6502
Updated: Feb 11, 2022
Since this blog is very new, I provided some background to my 6502 here.
I've been researching ways to add mouse support to my 6502 build. Options that came to mind:
Serial mouse connected through 65C51 ACIA.
PS2 mouse connected through 65C22 VIA.
USB mouse connected through some sort of a USB interface IC, such as a CH375.
Leverage existing libraries for Arduino USB support, and connect Arduino to 6502.
For my first attempt at a mouse, I started with option 4 -- leveraging libraries for Arduino.
The implementation I used consists of:
An Arduino Mega 2560 with a USB Host Shield that reads USB mouse data.
From the Arduino, trigger interrupts on the VIA and write mouse data to VIA ports.
In 6502 assembly, handle the interrupts, read the mouse data, and use that data for some purpose. In my case, I used the mouse data in my 6502 "paint" program.
The start to this solution came from lingib's writeup, Connect a USB Mouse to Your Arduino. As part of the implementation of the BME 280 sensor in my system, I had added an Arduino Mega 2560, communicating via serial to the 6502, to offload temperature and humidity adjustment calculations. As I was only using TX1/RX1 on the Arduino, I could do more with it. Lingib's writeup covers how to add a USB Host Shield to an Arduino Mega and receive USB data, such as movement direction, position, and button clicks. I added the USB Host Shield to my Arduino and connected the Arduino to one of the VIAs.
Connect GND from the Arduino to the 6502 circuit. Connect A1 on the Arduino to CA2 on the VIA; this will be used to trigger interrupts on the VIA from the Arduino. Then, connect the data lines from the Arduino to the VIA, based on the following:
I built upon lingib's Arduino code to interpret the mouse data, write data to a 6502 VIA, and trigger an interrupt on the VIA. Here's an example snippet that writes to the VIA and interrupt line based on the mouse directional data:
In the code on the 6502, I handle the interrupts that are raised by the Arduino and call a routine to handle each specific case (e.g., move left, move right, left button click).
In my specific case, in those handlers, I move the pixel on the screen or toggle drawing/colors, etc.
The full code for the Arduino can be found here: Arduino code.
The full code for the 6502 can be found here: 6502 code. There's a lot of noise in that file, so you'll want to just focus on the VIA 5 interrupt handling. Key sections:
VIA 5 address definitions.
Mouse bit definitions (covered earlier above).
VIA 5 interrupt configuration in setup:.
VIA5_CB1_handler: (split up to manage branch destinations out of range issues)
I imagine there are endless improvements that could be made to the 6502 assembly code. The mouse action is far from perfect, but I think it can be tweaked in code at this point. If you have suggestions to improve the code, please drop me a note.
As far as the overall solution, I know there are better ways that can be implemented to support a USB mouse. Thoughts that come to mind:
Use a couple of external shift registers between the VIA and the Arduino. This would let me get away with fewer VIA connections -- down to a single port instead of using both ports. I will likely try this in the near future.
SPI communication between the Arduino and VIA. This would take even fewer connections.
Forego the Arduino, and leverage something like a CH375. Anurag Chugh shared this article: Interface USB Mouse to your Arduino using CH375B. I have a slightly different version of the CH375. I believe either version could be used to interface a USB mouse from a VIA, without the Arduino.
I probably missed some important details above. If so, please let me know. Thanks!
I have updated the Arduino and 6502 assembly to support a reduction in the number of data lines between the Arduino and the VIA (down to six data lines plus interrupt line). A second VIA port is no longer needed. Updated code links below.