In one of Adrian's Digital Basement videos about the SWTPC 6800 he mentioned that by default the machine bit-bangs serial data at 300baud instead of having dedicated UART hardware.
I found this very interesting and read up on the UART protocol. The next step was to get out an Arduino and my little USB logic analyzer and tried to see if I can modify the blink sketch to output serial data ... and sure enough without too much hassle, I was able to write some bytes that the logic analyzer could display.
Great! now I have a solution looking for a problem. :)
On the shelve in my study, I spot the Atari 2600 with a breadboard attached from a previous project ... and that gave me an idea ... what if I add some RAM and ROM through the cartridge port and use the joystick port to bit-bang the serial data ... I will then have a Ben Eater style breadboard based computer but with less effort.
So I started wiring up the ROM without issue but when I got to the RAM I realized that there is no ReadWrite line from the CPU exposed on the cartridge port so I thought about it for a bit and decided to use the one address line for write-enable on the RAM. The Atari 2600 cartridge port can only address 4K of memory by default (without fancy bank switching).
My original idea was 2K of ROM and 2K of RAM but since I now have to use one of the address lines as write-enable I will only have 1K of RAM ... but that is fine right? Why would anyone require more than 1K of RAM? ;)
I did think of some other options like running a jumper wire from the CPU or using one of the bits on the joystick port to toggle the write-enable on the RAM, but I didn't want to make any changes to the Atari itself, and using one of the bits on the joystick port would mean that I have to run a jumper from joystick port to the cartridge and that also did not seem very elegant ... and again I'm fine with 1K.
Now that the hardware is sorted I needed to turn my attention to the software. I have not done a lot of development in 6502 assembly, however there are some great resources and tutorials on the web and specifically for the Atari 2600.
Again I started with a simple program just "blinking" a bit on the Atari's RIOT chip's port A (also known as the joystick port) and that also worked, and I was able to fairly quickly start bit-banging out serial data, however not at a standard baud rate.
Again looking at forum posts and code for Atari 2600 games I found out about the timer on the RIOT chip. Using the logic analyzer and by trial and error, I found a value that I could put into the timer that would give very close to a standard 1200 baud rate. I also learned that at least at these slower rates that UART can be pretty forgiving.
After getting this far, I took a break because I knew the next step would be to read bytes back over serial and I was not sure how I was going to do it, however, I was sure it was not going to be easy to get the timing right.
a day or two later I tried my first attempt at reading data, again by using the RIOT timer and to my surprise, the code worked the first time! I did mess with it and try to optimize it but that just broke it so I reverted to my first attempt.
Awesome so now I have working BIOS routines all I need now is the rest of the firmware.
Early on I already knew I wanted to try and port Wozmon but that was more of a stretch goal, however everything was going so well that I now was confident it could be done.
Going through Steve Wozniak's code I could see there was a subroutine (ECHO) for writing to the Apple 1 display and a memory location that he checked for keyboard presses. All I needed to do was to replace the "ECHO" subroutine with my own character-out routine and update the Wozmon code to instead of checking a memory location for key presses call my subroutine for reading bytes over serial. One last thing I had to do was to update the code that when it writes to RAM it offsets the address to enable write-enable on the RAM chip.
And it worked! well almost but not quite ... well not at all. I could see the prompt, I could type in commands, indicating that my RAM and input-output routines were working but it will always give incorrect results when reading from memory. The problem was that on the Atari 2600 the TIA (television interface adapter) was mapped into the zero-page memory space ... It took me way longer than I would like to admit to figure this out, however, once I did, it was just a matter of moving some memory declarations around to start after 0x80 in zero-page and finally it worked for real! I could write to memory and read it back without any issues.
I then wrote a Python script to read compiled 6502 assembly and spit out the Wozmon commands for loading the data into memory. I was then able to write a little "Hello World" program and upload it through a terminal emulator on my pc and sure enough that also worked!
So there was only one last thing I wanted to try ... remember that TIA chip I mentioned earlier ... the thing that makes the Atari 2600 an Atari 2600? I wanted to upload some code from the terminal emulator to interact with the chip and display something on the TV.
I found this great tool https://alienbill.com/2600/atari-background-builder/ for creating splash screens for Atari 2600 games and used it to create the assembly code for drawing an Apple logo. I then compiled the assembly and ran it through my python script and uploaded it through the terminal emulator. I had to play with the character and line-end delays in the terminal emulator but was able to get it so that it loads the data pretty reliably. After all that 'n typed in the run command and the Apple logo appeared on the TV screen!
The source code and some additional details are available on my GitHub page ... https://github.com/dadecoza/wozmon2600